#!/usr/bin/perl
#Copyright (c) 2006, Midwest Connections Inc.
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Midwest Connections Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
#FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
#DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
#SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#written by Zane C. Bowers <zanecb@midwest-connections.com>
#
#
#Note: Was originally planned to be named MWCQARGUGAU. This stood for
#MidWest Connection's Qmail Assign & Recipients Generator Using
#Groups And Users, but that was to bulky and awkward.
use strict;
use warnings;
use Getopt::Std;
use Term::ANSIColor;
#version
sub main::VERSION_MESSAGE {
print "QAR-Bufo v. 1.3.1\n";
}
sub main::HELP_MESSAGE {
print "\nqar-bufo [ -a " ; print color 'underline' ; print "assign file" ; print color 'reset'; print " ] ";
print " [ -r " ; print color 'underline' ; print 'recipient file' ; print color 'reset'; print " ]";
print " [ -v " ; print color 'underline' ; print 'virtualdomains files' ; print color 'reset'; print " ]\n";
print " [ -d " ; print color 'underline' ; print 'domains files' ; print color 'reset'; print " ]";
print " [ -g " ; print color 'underline' ; print 'groups' ; print color 'reset'; print " ]";
print " [ -e ]\n";
print "\n\n-a should be the file you wish to dump the QMail assign out to.\n".
" default: /var/qmail/users/assign\n\n".
"-r should be the file you wish to dump the QMail recipient list out to.\n".
" default: /var/qmail/users/recipients\n\n".
"-v should be a comma seperated list of files to pull the virtual domains from.\n".
" default: /var/qmail/control/virtualdomains.\n\n".
"-d should be a comma seperated list of files to pull the domains from.\n".
" default: /var/qmail/control/me\n".
" /var/qmail/control/locals\n".
" /var/qmail/control/rcpthosts\n".
" /var/qmail/control/defaultdomain\n\n",
"-g should be a comma seperated list of groups.\n".
" default: SMTPaccess\n".
" SMTPrecieveonly\n\n".
"-e tells it to look for extension address.\n".
" default: don't check\n";
exit 1;
};
#get supplied options
my %opts=();
getopts('a:r:ev:d:g:', \%opts);
#a = output assign to file
#r = output recipients to file
#e = if present check for extension address and allow them
#v = virtual domains files to use
#d = domains files to use
#g = groups to use
#get what file to sue for assign output
my $assign_out="/var/qmail/users/assign";
if (defined($opts{a})){
$assign_out=$opts{a};
};
#get what file to use for recipients output
my $recipient_out="/var/qmail/users/recipients";
if (defined($opts{r})){
$recipient_out=$opts{r};
};
#checks if it should check extensions or not. If it is defined it should.
my $extension_check="0";
if (defined($opts{e})){
$extension_check="1";
}
#checks what virtual domain files to use
my @virtual_domains_files=("/var/qmail/control/virtualdomains");
if (defined($opts{v})){
@virtual_domains_files=split(/,/,$opts{v});
};
#checks what domain files to use
my @domains_files=("/var/qmail/control/me",
"/var/qmail/control/locals",
"/var/qmail/control/rcpthosts",
"/var/qmail/control/defaultdomain");
if (defined($opts{d})){
@domains_files=split(/,/,$opts{d});
};
#checks what groups to check for users in
my @groups=("SMTPaccess","SMTPrecieveonly");
if (defined($opts{g})){
@groups=split(/,/,$opts{g});
};
#used for holding users
my %users_hash=();
#used for intering throught the group list
my $group_inter="0";
#runs through building a list of users
while (defined($groups[$group_inter])){
my ($name,$passwd,$gid,$members) = getgrnam($groups[$group_inter]);
#breaks the members string down into it's members
if (defined($members)){
my @gmembers=split(/ /,$members);
my $gmembers_inter="0";
while(defined($gmembers[$gmembers_inter])){
$users_hash{$gmembers[$gmembers_inter]}="";
$gmembers_inter++;
};
}else{
print $groups[$group_inter]." does not exist on this system. Continueing to process the rest.\n";
};
$group_inter++;
};
#converts it to a array for easy handling later
my @users_array=keys(%users_hash);
#used for intertering the domain list
my $domains_inter="0";
#used for holding the domains
my %domains_hash=();
#runs through building a list of domains
while (defined($domains_files[$domains_inter])){
#reads each domain and put it into the list.
if (-f $domains_files[$domains_inter]){
#read the file and put it in a array.
my @domains_temp_array=();
open(DOMAINSFILEREAD,$domains_files[$domains_inter])||die"Could not open $domains_files[$domains_inter]\n";;
@domains_temp_array=<DOMAINSFILEREAD>;
close(DOMAINSFILEREAD);
#used for intering through the list
my $domains_temp_array_inter="0";
#runs through it adding each line to the %domains_hash hash.
while (defined($domains_temp_array[$domains_temp_array_inter])){
#removes the line return
chomp($domains_temp_array[$domains_temp_array_inter]);
$domains_hash{$domains_temp_array[$domains_temp_array_inter]}="";
$domains_temp_array_inter++;
};
}else{
print $domains_files[$domains_inter]." does not exist. Continueing with the rest.\n";
};
$domains_inter++;
};
#converts the domains hash to a array for easier handling later.
my @domains_array=keys(%domains_hash);
#used for intertering the domain list
my $virtual_domains_inter="0";
#used for holding the domains
my %virtual_domains_hash=();
my %virtual_domains_domains=();
#runs through building a list of virtual domains
while (defined($virtual_domains_files[$virtual_domains_inter])){
if (-f $virtual_domains_files[$virtual_domains_inter]){
#read the file and put it in a array.
my @virtual_domains_temp_array=();
open(VIRTUALDOMAINSFILEREAD,$virtual_domains_files[$virtual_domains_inter])||die"Could not open $virtual_domains_files[$domains_inter]\n";;
@virtual_domains_temp_array=<VIRTUALDOMAINSFILEREAD>;
close(VIRTUALDOMAINSFILEREAD);
#used for intering through the list
my $virtual_domains_temp_array_inter="0";
#runs through it adding each line to the %domains_hash hash.
while (defined($virtual_domains_temp_array[$virtual_domains_temp_array_inter])){
#removes the line return
chomp($virtual_domains_temp_array[$virtual_domains_temp_array_inter]);
$virtual_domains_hash{$virtual_domains_temp_array[$virtual_domains_temp_array_inter]}="";
my @virtual_domains_split=split(/:/,$virtual_domains_temp_array[$virtual_domains_temp_array_inter]);
$virtual_domains_domains{$virtual_domains_split[0]}="";
$virtual_domains_temp_array_inter++;
};
}else{
print $virtual_domains_files[$virtual_domains_inter]." does not exist. Continueing with the rest.\n";
};
$virtual_domains_inter++;
};
#converts the domains hash to a array for easier handling later.
my @virtual_domains_array=keys(%virtual_domains_hash);
#this goes through and begins generating the assign file
my $users_array_inter="0"; #will be used for intering throught the array
my $assign_file=""; #holds what will be printed to the assign file
while (defined($users_array[$users_array_inter])){
my ($name,$passwd,$uid,$gid, $quota,$comment,
$gcos,$dir,$shell,$expire) = getpwnam($users_array[$users_array_inter]);
if ($extension_check == "1"){
$assign_file=$assign_file."+".$name."-:".$name.":".$uid.":".$gid.":".$dir.":-::\n";
};
#my $assign_line="=".$name.":".$name.":".$uid.":".$gid.":".$dir.":::\n";
#print $assign_line;
$assign_file=$assign_file."=".$name.":".$name.":".$uid.":".$gid.":".$dir.":::\n";
$users_array_inter++;
};
#this tags on the . needed for the assign file
$assign_file=$assign_file.".\n";
#This goes through begins generating the recipient file for the users.
$users_array_inter=0; #reset it back to 0.
my $recipient_file="";
while (defined($users_array[$users_array_inter])){
my $domains_array_inter=0;
#skips over the domain if it is a virtual domain
while (defined($domains_array[$domains_array_inter])){
if (! defined($virtual_domains_domains{$domains_array[$domains_array_inter]})){
#check for extension addresses if needed
if ($extension_check == "1"){
my ($name,$passwd,$uid,$gid, $quota,$comment,
$gcos,$dir,$shell,$expire) = getpwnam($users_array[$users_array_inter]);
#get a list of files matching .qmail-
opendir(DOTQMAILFIND, $dir);
my @rawhomedir=readdir(DOTQMAILFIND);
close DOTQMAILFIND;
my @dotqmailfiles=grep(/.qmail-/,@rawhomedir);
#goes through each one and generates a line for them.
my $dotqmailfilesinter=0;
while (defined($dotqmailfiles[$dotqmailfilesinter])){
#removes .qmail- from the begining of it
$dotqmailfiles[$dotqmailfilesinter]=~s/^.qmail-//;
#adds it to the recpient file string
$recipient_file=$recipient_file.$users_array[$users_array_inter]."-"
.$dotqmailfiles[$dotqmailfilesinter]."@"
.$domains_array[$domains_array_inter]."\n";
$dotqmailfilesinter++;
};
};
#adds it to the recipient file string
$recipient_file=$recipient_file.$users_array[$users_array_inter]."@"
.$domains_array[$domains_array_inter]."\n";
};
$domains_array_inter++;
};
$users_array_inter++;
};
#this goes through and begins generating a list of recipients for virtual domains
my $virtual_domains_array_inter="0";
while (defined($virtual_domains_array[$virtual_domains_array_inter])){
chomp $virtual_domains_array[$virtual_domains_array_inter];
#split it appart into the domain and the user who has it
my ($virtual_domain, $virtual_domain_user) = split(/:/,$virtual_domains_array[$virtual_domains_array_inter]);
#gets the info for the user that has the domain
my ($name,$passwd,$uid,$gid, $quota,$comment,
$gcos,$dir,$shell,$expire) = getpwnam($virtual_domain_user);
#get a list of files matching .qmail-
opendir(DOTQMAILFIND, $dir);
my @rawhomedir=readdir(DOTQMAILFIND);
close DOTQMAILFIND;
my @dotqmailfiles=grep(/.qmail-/,@rawhomedir);
#goes through each one and generates a line for them.
my $dotqmailfilesinter=0;
while (defined($dotqmailfiles[$dotqmailfilesinter])){
#removes .qmail- from the begining of it
$dotqmailfiles[$dotqmailfilesinter]=~s/^.qmail-//;
#adds it to the recpient file string
$recipient_file=$recipient_file.$dotqmailfiles[$dotqmailfilesinter]."@".$virtual_domain."\n";
$dotqmailfilesinter++;
};
$virtual_domains_array_inter++;
};
open(ASSIGNWRITE,">",$assign_out)||die("Could note open ".$assign_out." to write the assign file\n");
print ASSIGNWRITE $assign_file;
close(ASSIGNWRITE);
open(RECIPIENTWRITE,">",$recipient_out)||die("Could note open ".$recipient_out." to write the recipeint file\n");
print RECIPIENTWRITE $recipient_file;
close(RECIPIENTWRITE);
#run qmail-newu and qmail-recipients
system("/var/qmail/bin/qmail-newu");
system("/var/qmail/bin/qmail-recipients");
exit 0;
#-----------------------------------------------------------
# POD documentation section
#-----------------------------------------------------------
=head1 NAME
qar-bufo - Generate assign and recipient files for QMail.
=head1 SYNOPSIS
qar-bufo [B<-a> assign file] [B<-b> recipient file] [B<-b> virtualdomains files]
[B<-d> domains files] [B<-g> groups] [B<-e>]
=head1 OPTIONS
=item B<-a> assign output file
This should be the file you wish to dump the QMail assign out to. The
default is /var/qmail/users/assign.
=item B<-r> recipients output file
This should be the file you wish to dump the QMail recipient list out to. The
default is /var/qmail/users/recipients.
=item B<-v> virtualdomains files
This should be a comma seperated list of files to pull the virtual domains from.
The defualt is /var/qmail/control/virtualdomains.
=item B<-d> domains files
This should be a comma seperated list of files to pull the domains from. The
defaults are /var/qmail/control/me, /var/qmail/control/locals, /var/qmail/control/rcpthosts,
and /var/qmail/control/defaultdomain.
=item B<-g> groups
This should be a comma seperated list of groups. The defaults are SMTPaccess and SMTPrecieveonly.
=item B<-e>
Tells it to look for extension address for each user. By default it does not do this.
=head1 TODO
=item Finish writing the pod.
=head1 NOTES
Was originally planned to be named MWCQARGUGAU. This stood for
MidWest Connection's Qmail Assign & Recipients Generator Using
Groups And Users, but that was to bulky and awkward. QAR-Bufo
sounded so much nicer and much cooler.
=head1 AUTHOR
Copyright (c) 2006, Midwest Connections Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Midwest Connections Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
written by Zane C. Bowers <zanecb@midwest-connections.com>
=head1 SCRIPT CATEGORIES
Unix/System_administration
=head1 OSNAMES
any
=head1 README
qar-bufo generates the Qmail assign and recipients file based on unix groups.
=head1 CHANGELOG
=item 2006-09-12 1.3.1
Fixed a problem with it skipping over some domian names for when generating the recipient list.
=item 2006-09-11 1.3.0
Run qmail-newu and qmail-recipients.
=item 2006-09-11 1.2.0
Fixed a problem with it not putting . on the end of the assign and fixed the recipient gen so it does not put every one in every virtual domain.
=item 2006-09-08 1.1.0
Updated the POD.
=cut
#-----------------------------------------------------------
# End of POD documentation
#-----------------------------------------------------------
syntax highlighted by Code2HTML, v. 0.9.1