###
### Copyright 2000-2007 University of Illinois Board of Trustees
### All rights reserved.
###
### sendmail.pm - sendmail module for psgconf
###
### Campus Information Technologies and Educational Services
### University of Illinois at Urbana-Champaign
###
package PSGConf::Control::sendmail;
use strict;
use File::Basename;
use File::stat;
use PSGConf::Action::GenerateFile::sendmail_aliases;
use PSGConf::Action::GenerateFile::sendmail_mc;
use PSGConf::Action::GenerateFile::sendmail_cf;
use PSGConf::Action::GenerateFile::sendmail_trusted_users;
use PSGConf::Action::GenerateFile::sendmail_map;
use PSGConf::Action::MkDir;
use PSGConf::Action::RunCommand;
use PSGConf::Action::RestartDaemon;
use PSGConf::Data::Boolean;
use PSGConf::Data::List;
use PSGConf::Data::Hash;
use PSGConf::Data::Integer;
use PSGConf::Data::String;
use PSGConf::Control::Packages qw(_add_pkgs);
use PSGConf::Control::syslog qw(_add_syslog);
###############################################################################
### plugin function for PSGConf::Action::RunCommand
###############################################################################
sub _check_map
{
my ($self, $psgconf) = @_;
my ($action, $ext, $st, $st2, $found, $cnt);
$action = $psgconf->get_action($self->{filename});
return 1
if (defined($action) && $action->changed());
$st = stat $self->{filename};
###
### Originally I was going to use the DATABASE_MAP_TYPE to determine
### which extension to look for against the alias file, but I found
### some sendmail installations would use one format for most maps but
### the aliases file was a different format. Now I am going to check
### and make sure that I find at least one file that is newer. If ALL
### of the map files that we find are out of date, then run newaliases.
###
$found = $cnt = 0;
foreach $ext ( 'db', 'dir', 'pag') {
if ( -f $self->{filename} . '.' . ${ext} ) {
$found++;
$st2 = stat $self->{filename} . '.' . ${ext};
### If our map file is newer than the
### .dir/.pag or .db files, then cause the
### map command to be rerun.
$cnt++
if ( $st->mtime > $st2->mtime );
}
}
return ($cnt == $found)? 1: 0;
}
###############################################################################
### policy methods
###############################################################################
### set up rc scripts
sub _policy_add_rc_scripts
{
my ($self, $psgconf) = @_;
my ($start_cmd);
### FIXME: Put this into the config files instead
### set start command
$start_cmd = $psgconf->data_obj('sendmail_path')->get() . ' -bd -q20m \
&& ' . $psgconf->data_obj('rc_echo')->get() . ' " (MTA)\c"
if [ -s ' . $psgconf->data_obj('sendmail_cf_dir')->get() . '/submit.cf ]; then
' . $psgconf->data_obj('sendmail_path')->get() . ' -L sm-msp -Ac -q20m \
&& ' . $psgconf->data_obj('rc_echo')->get() . ' ", (MSP)\c"
fi';
$start_cmd =~ s/-q20m/-qp/
if ($psgconf->data_obj('sendmail_use_persistent_queue_runners')->equals('true'));
$psgconf->data_obj('rc_scripts')->insert(
{ 'sendmail' => {
'state' => 'enable',
'start_cmd' => $start_cmd
}
}
) if ( $psgconf->data_obj('sendmail_enable')->equals('true') );
}
### add TCP wrappers entry
sub _policy_add_tcpwrapper_entry
{
my ($self, $psgconf) = @_;
### NOTE: Adding sendmail wrappers for all platforms, but I think
### the only ones that need it are FreeBSD, RHEL3+, and Solaris 10
return
if ( $psgconf->data_obj('sendmail_enable')->equals('false') );
$psgconf->data_obj('tcp_wrappers')->insert_row(
{ 1 => 'all' },
[ 'sendmail', 'ALL', 'allow' ]
)
if (! $psgconf->data_obj('tcp_wrappers')->find_row(
{ 0 => qr/\bsendmail\b/ }));
}
### add smmsp user and group
sub _policy_add_user
{
my ($self, $psgconf) = @_;
return
if ($psgconf->data_obj('sendmail_enable')->equals('false'));
$psgconf->data_obj('group_info')->insert(
{ $psgconf->data_obj('sendmail_msa_group')->get() => {
'recommended_gid' => $psgconf->data_obj('sendmail_msa_gid')->get()
}
}
) if (!defined $psgconf->data_obj('group_info')->find(
$psgconf->data_obj('sendmail_msa_group')->get()));
$psgconf->data_obj('user_info')->insert(
{ $psgconf->data_obj('sendmail_msa_user')->get() => {
'recommended_uid' => $psgconf->data_obj('sendmail_msa_uid')->get(),
'passwd' => $psgconf->data_obj('passwd_token')->get(),
'group' => $psgconf->data_obj('sendmail_msa_group')->get(),
'gecos' => 'sendmail message submission program',
'home' => '/var/spool/clientmqueue'
}
}
) if (!defined $psgconf->data_obj('user_info')->find(
$psgconf->data_obj('sendmail_msa_user')->get()));
}
### set confPID_FILE option
sub _policy_default_pidfile
{
my ($self, $psgconf) = @_;
return
if ($psgconf->data_obj('sendmail_enable')->equals('false'));
$psgconf->data_obj('sendmail_options')->insert(
{ 'confPID_FILE' =>
$psgconf->data_obj('pidfile_dir')->get() . '/sendmail.pid'
}
) if (!defined $psgconf->data_obj('sendmail_options')->find('confPID_FILE'));
}
### set default trusted-users file
sub _policy_default_ct_file
{
my ($self, $psgconf) = @_;
return
if ($psgconf->data_obj('sendmail_enable')->equals('false'));
if (!defined $psgconf->data_obj('sendmail_options')->find('confCT_FILE')
&& $psgconf->data_obj('sendmail_trusted_users')->count()) {
$psgconf->data_obj('sendmail_options')->insert(
{ 'confCT_FILE' => '-o '
. $psgconf->data_obj('sendmail_cf_dir')->get()
. '/trusted-users' }
);
$psgconf->data_obj('sendmail_features')->insert(
{ 'use_ct_file' => undef }
);
}
}
my %_default_aliases = (
postmaster => 'root',
'MAILER-DAEMON' => 'postmaster',
nobody => '/dev/null'
);
### set default aliases
sub _policy_default_aliases
{
my ($self, $psgconf) = @_;
my ($aliases);
$aliases = $psgconf->data_obj('sendmail_aliases')->get();
map {
$psgconf->data_obj('sendmail_aliases')->insert(
{ $_ => $_default_aliases{$_} }
) if (!defined $psgconf->data_obj('sendmail_aliases')->find($_));
} keys %_default_aliases;
}
###############################################################################
### decide() method
###############################################################################
sub _add_queue_dirs
{
my ($self, $psgconf, $qdir, $uid, $gid) = @_;
$psgconf->register_actions(
PSGConf::Action::MkDir->new(
name => $qdir,
mode => $psgconf->data_obj('sendmail_queue_mode')->get(),
uid => $uid,
gid => $gid
),
($psgconf->data_obj('sendmail_queue_qf_subdirs')->equals('true')
? (map {
PSGConf::Action::MkDir->new(
name => "$qdir/$_",
mode => $psgconf->data_obj('sendmail_queue_mode')->get(),
uid => $uid,
gid => $gid
)
} qw(qf df xf))
: ()
),
);
}
sub decide
{
my ($self, $psgconf) = @_;
my ($smopts, $smfeatures, $qgrps);
my ($alias_file, $uid, $gid, $smmsp_gid, $smmsp_uid);
my ($platform, $access_map, $mailertable, $map_type, $map_path);
my ($num_queues, $qdir);
return
if ($psgconf->data_obj('sendmail_enable')->equals('false'));
$smopts = $psgconf->data_obj('sendmail_options')->get();
$smfeatures = $psgconf->data_obj('sendmail_features')->get();
$qgrps = $psgconf->data_obj('sendmail_queue_groups')->get();
$num_queues = $psgconf->data_obj('sendmail_num_queues_per_group')->get();
$alias_file = $smopts->{'ALIAS_FILE'};
$alias_file =~ s|,.*||;
$smmsp_uid = $psgconf->data_obj('user_info')->find(
$psgconf->data_obj('sendmail_msa_user')->get()
)->{'uid'};
$smmsp_gid = $psgconf->data_obj('group_info')->find(
$psgconf->data_obj('sendmail_msa_group')->get()
)->{'gid'};
$uid = ( defined $psgconf->data_obj('user_info')->find($psgconf->data_obj('sendmail_mta_user')->get()))?
$psgconf->data_obj('user_info')->find($psgconf->data_obj('sendmail_mta_user')->get())->{'uid'}:
25;
$gid = ( defined $psgconf->data_obj('group_info')->find($psgconf->data_obj('sendmail_mta_group')->get()))?
$psgconf->data_obj('group_info')->find($psgconf->data_obj('sendmail_mta_group')->get())->{'gid'}:
25;
foreach $qdir ($smopts->{'QUEUE_DIR'},
map { $_->{Path} }
grep { exists($_->{Path}) }
(values %$qgrps))
{
if (substr($qdir, -1, 1) ne '*')
{
$self->_add_queue_dirs($psgconf, $qdir, $uid, $gid);
next;
}
map {
$self->_add_queue_dirs(
$psgconf,
sprintf('%s%0*d',
substr($qdir, 0, length($qdir) - 1),
length("$num_queues"),
$_),
$uid,
$gid
);
} (1 .. $num_queues);
}
$psgconf->register_actions(
PSGConf::Action::MkDir->new(
'name' => $smopts->{'confHOST_STATUS_DIRECTORY'},
'uid' => $uid,
'gid' => $gid
)
)
if (exists($smopts->{'confHOST_STATUS_DIRECTORY'}));
$psgconf->register_actions(
PSGConf::Action::MkDir->new(
'name' => '/var/spool/clientmqueue',
'uid' => $smmsp_uid,
'gid' => $smmsp_gid,
'mode' => 0770
),
PSGConf::Action::GenerateFile::sendmail_mc->new(
'name' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/sendmail.mc',
'comment_str' => 'dnl',
'description' => 'sendmail configuration file',
'ostype' => $psgconf->data_obj('sendmail_ostype')->get(),
'versionid' => 'sendmail.mc - generated by ' . $0,
'uid' => $uid,
'gid' => $gid,
'defines' => $smopts,
'features' => $smfeatures,
'masquerade_as' => $psgconf->data_obj('sendmail_masquerade_as')->get(),
'exposed_users' => $psgconf->data_obj('sendmail_exposed_users')->get(),
'mailers' => [ qw(local smtp) ],
'queue_groups' => $psgconf->data_obj('sendmail_queue_groups')->get(),
'literal' => $psgconf->data_obj('sendmail_literal')->get()
),
PSGConf::Action::GenerateFile::sendmail_cf->new(
'name' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/sendmail.cf',
'comment_str' => undef,
'uid' => $uid,
'gid' => $gid,
'user' => $psgconf->data_obj('sendmail_mta_user')->get(),
'mc_file' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/sendmail.mc',
'm4_command' => $psgconf->data_obj('sendmail_m4_command')->get(),
'sendmail_m4_dir' => $psgconf->data_obj('sendmail_m4_dir')->get()
),
PSGConf::Action::GenerateFile::sendmail_mc->new(
'name' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/submit.mc',
'comment_str' => 'dnl',
'description' => 'MSP configuration file',
'versionid' => 'submit.mc - generated by ' . $0,
'uid' => $smmsp_uid,
'gid' => $smmsp_gid,
'defines' => {
confCF_VERSION => 'Submit',
__OSTYPE__ => '',
_USE_DECNET_SYNTAX_ => 1,
confTIME_ZONE => 'USE_TZ',
confDONT_INIT_GROUPS => 'true',
'confCT_FILE' => '-o '
. $psgconf->data_obj('sendmail_cf_dir')->get()
. '/trusted-users',
confPID_FILE => $psgconf->data_obj('pidfile_dir')->get() . '/sm-client.pid'
},
'features' => {
use_ct_file => undef
},
### the msp feature must come at the end,
### regardless of sort order
'literal' => 'FEATURE(`msp\')dnl'
),
PSGConf::Action::GenerateFile::sendmail_cf->new(
'name' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/submit.cf',
'comment_str' => undef,
'uid' => $smmsp_uid,
'gid' => $smmsp_gid,
'mc_file' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/submit.mc',
'user' => $psgconf->data_obj('sendmail_mta_user')->get(),
'm4_command' => $psgconf->data_obj('sendmail_m4_command')->get(),
'sendmail_m4_dir' => $psgconf->data_obj('sendmail_m4_dir')->get()
),
PSGConf::Action::GenerateFile::sendmail_trusted_users->new(
'name' => $psgconf->data_obj('sendmail_cf_dir')->get() . '/trusted-users',
'description' => 'trusted users file',
'uid' => $uid,
'gid' => $gid,
'trusted_users' => [ keys %{$psgconf->data_obj('sendmail_trusted_users')->get()} ]
),
PSGConf::Action::GenerateFile::sendmail_aliases->new(
'name' => $alias_file,
'description' => 'Local mail aliases',
'uid' => $uid,
'gid' => $gid,
'aliases' => $psgconf->data_obj('sendmail_aliases')->get()
),
PSGConf::Action::RestartDaemon->new(
name => 'sendmail',
pidfile => $psgconf->data_obj('sendmail_options')->find('confPID_FILE'),
filename =>
[ $psgconf->data_obj('sendmail_cf_dir')->get() . '/sendmail.cf',
$psgconf->data_obj('sendmail_cf_dir')->get() . '/trusted-users' ]
),
PSGConf::Action::RestartDaemon->new(
name => 'msp',
pidfile => '/var/spool/clientmqueue/sm-client.pid',
filename =>
[ $psgconf->data_obj('sendmail_cf_dir')->get() . '/submit.cf',
$psgconf->data_obj('sendmail_cf_dir')->get() . '/trusted-users' ]
),
PSGConf::Action::RunCommand->new(
name => 'sendmail alias file',
command => $psgconf->data_obj('sendmail_newaliases_command')->get()
. ' -C '
. $psgconf->data_obj('sendmail_cf_dir')->get()
.'/sendmail.cf',
check_func => \&_check_map,
filename => $alias_file
)
);
$access_map = $psgconf->data_obj('sendmail_access_map')->get();
if (%$access_map
&& exists($smfeatures->{access_db}))
{
$map_type = $smfeatures->{access_db};
$map_type =~ s/\s.*//;
$map_type = $smopts->{DATABASE_MAP_TYPE}
if ($map_type eq 'DATABASE_MAP_TYPE');
$map_path = $smfeatures->{access_db};
$map_path = (split(/\s+/, $map_path))[-1];
$psgconf->register_actions(
PSGConf::Action::GenerateFile::sendmail_map->new(
name => $map_path,
description => 'sendmail access map',
entries => $access_map
),
PSGConf::Action::RunCommand->new(
name => 'sendmail access map',
command => $psgconf->data_obj('sendmail_makemap_command')->get()
. ' '
. $map_type
. ' '
. $map_path
. ' < '
. $map_path,
check_func => \&_check_map,
filename => $map_path
)
);
}
$mailertable = $psgconf->data_obj('sendmail_mailertable')->get();
if (%$mailertable
&& exists($smfeatures->{mailertable}))
{
$map_type = $smfeatures->{mailertable};
$map_type =~ s/\s.*//;
$map_type = $smopts->{DATABASE_MAP_TYPE}
if ($map_type eq 'DATABASE_MAP_TYPE');
$map_path = $smfeatures->{mailertable};
$map_path = (split(/\s+/, $map_path))[-1];
$psgconf->register_actions(
PSGConf::Action::GenerateFile::sendmail_map->new(
name => $map_path,
description => 'sendmail mailertable',
'uid' => $uid,
'gid' => $gid,
entries => $mailertable
),
PSGConf::Action::RunCommand->new(
name => 'sendmail mailertable',
command => $psgconf->data_obj('sendmail_makemap_command')->get()
. ' '
. $map_type
. ' '
. $map_path
. ' < '
. $map_path,
check_func => \&_check_map,
filename => $map_path
)
);
}
}
###############################################################################
### Constructor
###############################################################################
sub new
{
my ($class, $psgconf) = @_;
my ($self, %smopts, $cf_dir);
$self = {};
bless($self, $class);
$cf_dir = '/etc/mail';
%smopts = (
'QUEUE_DIR' => '/var/spool/mqueue',
'ALIAS_FILE' => $cf_dir . '/aliases'
);
### So that _add_pkgs knows which directives to look at
$self->{name} = 'sendmail';
$self->{enable} = $self->{name} . '_enable';
$self->{packages} = $self->{name} . '_packages';
### So that _add_syslog knows which directives to look at
$self->{syslog} = 'mail';
$self->{facility} = $self->{syslog} . '.info';
$psgconf->register_data(
'sendmail_m4_command' => PSGConf::Data::String->new(
'value_abspath' => 1,
value => '/usr/bin/m4'
),
'sendmail_m4_dir' => PSGConf::Data::String->new(
'value_abspath' => 1,
'value' => '/usr/share/sendmail'
),
'sendmail_cf_dir' => PSGConf::Data::String->new(
'value_abspath' => 1,
'value' => $cf_dir
),
'sendmail_path' => PSGConf::Data::String->new(
'value_abspath' => 1,
value => '/usr/sbin/sendmail'
),
'sendmail_makemap_command'
=> PSGConf::Data::String->new(
'value_abspath' => 1,
value => '/usr/sbin/makemap'
),
'sendmail_newaliases_command' => PSGConf::Data::String->new(
'value_abspath' => 1,
value => '/usr/bin/newaliases'
),
'sendmail_enable' => PSGConf::Data::Boolean->new(
'value' => 'false'
),
'sendmail_packages' => PSGConf::Data::List->new(),
'sendmail_access_map' => PSGConf::Data::Hash->new(),
'sendmail_mailertable' => PSGConf::Data::Hash->new(),
'sendmail_aliases' => PSGConf::Data::Hash->new(),
'sendmail_features' => PSGConf::Data::Hash->new(
'value_optional' => 1
),
'sendmail_literal' => PSGConf::Data::String->new(),
'sendmail_masquerade_as'
=> PSGConf::Data::String->new(),
'sendmail_exposed_users' => PSGConf::Data::List->new(),
'sendmail_mta_user' => PSGConf::Data::String->new(
value => 'root'
),
'sendmail_mta_group' => PSGConf::Data::String->new(
value => 'daemon'
),
'sendmail_msa_user' => PSGConf::Data::String->new(
value => 'smmsp'
),
'sendmail_queue_mode' => PSGConf::Data::Integer->new(
value => 0755
),
'sendmail_msa_uid' => PSGConf::Data::Integer->new(
value => 25
),
'sendmail_msa_group' => PSGConf::Data::String->new(
value => 'smmsp'
),
'sendmail_msa_gid' => PSGConf::Data::Integer->new(
value => 25
),
'sendmail_ostype' => PSGConf::Data::String->new(),
'sendmail_options' => PSGConf::Data::Hash->new(
'value' => \%smopts
),
'sendmail_trusted_users'
=> PSGConf::Data::Hash->new(
'value_optional' => 1
),
'sendmail_queue_groups' => PSGConf::Data::Hash->new(
'value_type' => 'HASH'
),
'sendmail_queue_qf_subdirs'
=> PSGConf::Data::Boolean->new(
'value' => 'false'
),
'sendmail_num_queues_per_group'
=> PSGConf::Data::Integer->new(
value => 5
),
'sendmail_use_persistent_queue_runners'
=> PSGConf::Data::Boolean->new(
'value' => 'false'
)
);
$psgconf->register_policy($self,
sm_default_pidfile => '_policy_default_pidfile',
sm_default_ct_file => '_policy_default_ct_file',
sm_default_aliases => '_policy_default_aliases',
sm_add_rc_scripts => '_policy_add_rc_scripts',
sm_add_tcpwrapper_entry => '_policy_add_tcpwrapper_entry',
sm_add_packages => '_add_pkgs',
sm_add_syslog => '_add_syslog',
sm_add_user => '_policy_add_user'
);
return $self;
}
###############################################################################
### documentation
###############################################################################
1;
__END__
=head1 NAME
PSGConf::Control::sendmail - psgconf control class for sendmail
=head1 SYNOPSIS
In F<psgconf_modules>:
Control PSGConf::Control::sendmail
=head1 DESCRIPTION
The B<PSGConf::Control::sendmail> module provides a B<psgconf> control object
for configuring C<sendmail>. 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<sendmail_path>
A B<PSGConf::Data::String> object that contains the absolute path to the
C<sendmail> binary. The default is C</usr/sbin/sendmail>.
=item I<sendmail_makemap_command>
A B<PSGConf::Data::String> object that contains the C<makemap> command to
be used to generate map files. The default is C</usr/sbin/makemap>.
=item I<sendmail_newaliases_command>
A B<PSGConf::Data::String> object that contains the C<newaliases> command to
be used to generate alias files. The default is C</usr/bin/newaliases>.
=item I<sendmail_enable>
A B<PSGConf::Data::Boolean> object that indicates whether C<sendmail>
should be configured.
=item I<sendmail_packages>
A B<PSGConf::Data::List> object that lists all packages to install.
=item I<sendmail_aliases>
A B<PSGConf::Data::Hash> object that contains entries for the
F<aliases> file.
=item I<sendmail_access_map>
A B<PSGConf::Data::Hash> object that contains entries for the
access map.
=item I<sendmail_mailertable>
A B<PSGConf::Data::Hash> object that contains entries for the
mailertable.
=item I<sendmail_m4_command>
A B<PSGConf::Data::String> object that contains the C<m4> command to
be used by the B<PSGConf::Action::GenerateFile::sendmail_cf> object's
check() method. The default is C</usr/bin/m4>.
=item I<sendmail_m4_dir>
A B<PSGConf::Data::String> object that contains the absolute path to
the directory containing C<sendmail>'s C<m4> macros. The default is
F</usr/share/sendmail>.
=item I<sendmail_cf_dir>
A B<PSGConf::Data::String> object that contains the absolute path to
the directory containing C<sendmail>'s config files. The default is
F</etc/mail>.
=item I<sendmail_features>
A B<PSGConf::Data::Hash> object that contains the C<FEATURE()> macros
for the C<sendmail_cf_dir>F</sendmail.mc> file. The hash key is the name
of the feature, and the optional value is the argument. If the argument
is not enclosed in C<`'> quotes, they will be added.
=item I<sendmail_mta_user>
A B<PSGConf::Data::String> object that contains the name of the account
to own the sendmail queue directories and run the m4 command to build
F<sendmail.cf> files. Defaults to C<root>.
=item I<sendmail_mta_group>
A B<PSGConf::Data::String> object that contains the group name to own
the sendmail queue directories. Defaults to C<daemon>.
=item I<sendmail_msa_user>
A B<PSGConf::Data::String> object that contains the login for the
Sendmail Submission User. Defaults to C<smmsp>.
=item I<sendmail_msa_uid>
A B<PSGConf::Data::Integer> object that contains the recommended uid for
the B<sendmail_msa_user> account. Defaults to 25.
=item I<sendmail_msa_group>
A B<PSGConf::Data::String> object that contains the group name for the
Sendmail Submission User. Defaults to C<smmsp>.
=item I<sendmail_msa_gid>
A B<PSGConf::Data::Integer> object that contains the recommended gid for
the B<sendmail_msa_user> account. Defaults to 25.
=item I<sendmail_queue_mode>
A B<PSGConf::Data::Integer> object that contains the mode of the queue
directories. The default is 0755.
=item I<sendmail_literal>
A B<PSGConf::Data::String> object that contains literal text to add to
the end of the C<sendmail_cf_dir>F</sendmail.mc> file.
=item I<sendmail_masquerade_as>
A B<PSGConf::Data::String> object that contains a hostname for
C<sendmail> to masquerade as.
=item I<sendmail_exposed_users>
A B<PSGConf::Data::List> object that contains list of users to have
C<sendmail> expose, even when I<sendmail_masquerade_as> is set.
=item I<sendmail_ostype>
A B<PSGConf::Data::String> object that contains the value for the
C<OSTYP> feature macro for the sendmail mc file.
=item I<sendmail_options>
A B<PSGConf::Data::Hash> object that contains the macros to be
C<define()>ed in the C<sendmail_cf_dir>F</sendmail.mc> file. By default,
C<QUEUE_DIR> is set to F</var/spool/mqueue>, and C<ALIAS_FILE> is set to
C<sendmail_cf_dir>F</aliases>.
=item I<sendmail_trusted_users>
A B<PSGConf::Data::Hash> object whose keys are the list of C<sendmail>'s
trusted users.
=item I<sendmail_queue_groups>
A B<PSGConf::Data::Hash> object that contains the queue groups to be
configured in the C<sendmail_cf_dir>F</sendmail.mc> file. The hash key is the
name of the queue group, and the value is an anonymous hash containing
the attributes for that queue group.
=item I<sendmail_queue_qf_subdirs>
A B<PSGConf::Data::Boolean> object that indicates whether the C<qf>,
C<df>, and C<xf> queue subdirectories should be created.
B<NOTE:> If you enable this on a system where C<sendmail> is already
running, you must stop C<sendmail>, go to each queue directory and move
all C<qf?*> files to the C<qf> subdirectory and all C<df?*> files to
the C<df> subdirectory, and then restart C<sendmail>. Failure to do
this can result in lost messages!
=item I<sendmail_num_queues_per_group>
A B<PSGConf::Data::Integer> object that indicates the number of queues
to be created for each queue group. This is only relevant if either
I<sendmail_queue_groups> is set or if the value of the C<QUEUE_DIR>
entry in I<sendmail_options> ends with a C<*>.
=item I<sendmail_use_persistent_queue_runners>
A B<PSGConf::Data::Boolean> object that indicates whether persistent
queue runners should be used.
=back
The constructor also registers the following policy methods:
=over 4
=item I<sm_add_rc_scripts>
Sets up the C<sendmail> RC script. This is done using the I<rc_scripts>
data object, which are provided by the B<PSGConf::Control::InitScripts> module.
=item I<sm_add_user>
Adds the C<smmsp> user and group using the I<user_info> and
I<group_info> data objects, which are provided by the
B<PSGConf::Control::Users> module.
=item I<sm_add_tcpwrapper_entry>
Adds an entry for I<sendmail> to the I<tcp_wrappers> object (provided
by B<PSGConf::Control::TCPWrappers>).
=item I<sm_add_packages>
Requests that the C<sendmail> package be installed. This is done using
the I<pkg_install_list> object, which is provided by the
B<PSGConf::Control::Packages> module.
=item I<sm_default_pidfile>
If the I<sendmail_options> object does not contain an entry for
C<confPID_FILE>, set it to F<I<pidfile_dir>/sendmail.pid>. (The
I<pidfile_dir> object is provided by the B<PSGConf::Control::Core>
module.)
=item I<sm_default_ct_file>
If the I<sendmail_trusted_users> object has been set and the
I<sendmail_options> object does not contain an entry for C<confCT_FILE>,
set C<confCT_FILE> to C<-o sendmail_cf_dir/trusted-users> and add an entry
for C<use_ct_file> to the I<sendmail_features> object.
=item I<sm_default_aliases>
If there is no entry for C<postmaster> in the I<sendmail_aliases> data
object, set it to C<root>.
If there is no entry for C<MAILER-DAEMON> in the I<sendmail_aliases> data
object, set it to C<postmaster>.
If there is no entry for C<nobody> in the I<sendmail_aliases> data
object, set it to C</dev/null>.
=back
=item decide()
If I<sendmail_enable> is on, instantiates and registers action objects,
as follows:
=over 4
=item *
Registers B<PSGConf::Action::MkDir> action objects to create
any needed queue directories. The queue directories are
calculated based on the values of the I<sendmail_queue_groups> and
I<sendmail_num_queues_per_group> data objects and the C<QUEUE_DIR>
entry in the I<sendmail_options> object.
=item *
Registers a B<PSGConf::Action::MkDir> action object to create the
F</var/spool/clientmqueue> directory. The directory will be given mode
0770 with the group ID of the C<smmsp> group. (The group ID is obtained
from the I<group_info> object, which is provided by the
B<PSGConf::Control::Users> module.)
=item *
Registers B<PSGConf::Action::GenerateFile::sendmail_mc> action objects
to create the C<sendmail_cf_dir>F</sendmail.mc> and
C<sendmail_cf_dir>F</submit.mc> files.
=item *
Registers B<PSGConf::Action::GenerateFile::sendmail_cf> action objects
to create the C<sendmail_cf_dir>F</sendmail.cf> and
C<sendmail_cf_dir>F</submit.cf> files.
=item *
Registers a B<PSGConf::Action::GenerateFile::sendmail_trusted_users>
object to create the C<sendmail_cf_dir>F</trusted-users> file.
=item *
Registers a B<PSGConf::Action::GenerateFile::sendmail_aliases> action
object to create the F<aliases> file and a B<PSGConf::Action::RunCommand>
action object to run C<newaliases>. The path for the file is taken
from the C<ALIAS_FILE> entry in the I<sendmail_options> object.
The C<ALIAS_FILE> value will be truncated at the first C<,> character.
=item *
If C<confHOST_STATUS_DIRECTORY> is set in the I<sendmail_options> object,
registers a B<PSGConf::Action::MkDir> action object to create the
specified directory.
=item *
If I<sendmail_access_map> is set and I<sendmail_features> contains an
entry called C<access_db>, registers a
B<PSGConf::Action::GenerateFile::sendmail_map> object to create the
access map and a B<PSGConf::Action::RunCommand> object to run C<makemap>
on the new map file.
=item *
If I<sendmail_mailertable> is set, registers a
B<PSGConf::Action::GenerateFile::sendmail_map> object to create the
access map and a B<PSGConf::Action::RunCommand> object to run C<makemap>
on the new map file.
=back
=back
=head1 SEE ALSO
C<CE<lt>sendmail(8)E<gt>>
C<CE<lt>newaliases(1)E<gt>>
C<CE<lt>m4(1)E<gt>>
C<CE<lt>makemap(1)E<gt>>
L<perl>
L<PSGConf>
L<PSGConf::Action::GenerateFile::sendmail_aliases>
L<PSGConf::Action::GenerateFile::sendmail_mc>
L<PSGConf::Action::GenerateFile::sendmail_cf>
L<PSGConf::Action::GenerateFile::sendmail_trusted_users>
L<PSGConf::Action::GenerateFile::sendmail_map>
L<PSGConf::Action::MkDir>
L<PSGConf::Action::RunCommand>
L<PSGConf::Action::RestartDaemon>
L<PSGConf::Control::Core>
L<PSGConf::Control::InitScripts>
L<PSGConf::Control::Packages>
L<PSGConf::Control::TCPWrappers>
L<PSGConf::Control::Users>
L<PSGConf::Data::Boolean>
L<PSGConf::Data::Hash>
L<PSGConf::Data::String>
L<psgconf-intro>
=cut
syntax highlighted by Code2HTML, v. 0.9.1