Update of /cvsroot/tmda/tmda/contrib
In directory sc8-pr-cvs1:/tmp/cvs-serv11711/contrib

Modified Files:
        ChangeLog 
Added Files:
        update-internaldomains 
Removed Files:
        vipmap-to-authmap 
Log Message:
New script from Jesse Guardiani, `update-internaldomains'.

Removed `vipmap-to-authmap'. Jesse says:

  I've been looking at Tim's code, and it appears that the
  vipmap-to-authmap script is unnecessary. If an ipauthmap file
  doesn't exist then tmda-ofmipd defaults to the correct behavior,
  making the vipmap-to-authmap script redundant for vpopmail
  users. I've tested this on my production systems.


--- NEW FILE ---
#!/usr/bin/env perl

# --------------------------------------------------
#  update-internaldomains - atomically update global
#                           whitelist of internal
#                           domains
#                               
#  Author                 - Jesse D. Guardiani
#  Created                - 03/12/03
#  Modified               - 03/18/03
# --------------------------------------------------
# See 'update-internaldomains -h' for Usage
# instructions.
#         
#  ChangeLog
#  ---------
#
#  03/18/03 - JDG
#  --------------
#  - Added Usage text above.
#  - Made a few clarifications to the Usage() text
#  - Added the -a option
#  - Added Copyright and GNU statement
#
#  03/12/03 - JDG
#  --------------
#  - Created
# --------------------------------------------------
# Copyright (C) 2003 Jesse D. Guardiani <[EMAIL PROTECTED]>
#
# This file is part of TMDA.
#
# TMDA is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.  A copy of this license should
# be included in the file COPYING.
#
# TMDA is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with TMDA; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# --------------------------------------------------


use strict;

# -----------------------------------
# GLOBALS
# -----------------------------------

my $VERSION="0.001";         # Version number of this script
my $debug=0;                 # We default to non-debug mode
my $path_to_whitelist="";    # Path (relative or full) to whitelist
my $do_combine=0;            # boolean flag that specifies whether or not the output 
of $command should
                             # be combined with the contents of the file specified by 
-a
my $add_to_whitelist="addto-whitelist";
                             # Name of the file whos contents will be combined with 
$command's output
                             # if the file "$base_whitelist_dir/$add_to_whitelist" 
exists.
my $command="";              # Command to execute that will return a list of internal 
domains, one per line.
my $base_whitelist_dir="";   # Path to the whitelist's base directory, without a 
trailing slash.
my $tmp_file="";             # relative or full path to temporary file
my $owner="vpopmail";        # file owner. This is a candidate for a command line 
option someday.        
my $last_error="";           # Last Error code returned by back-tick called shell 
command




# -----------------------------------
# usage() function
# -----------------------------------

sub usage()
{
        print STDERR << "EOF";

------------------------------------------------------------------------
usage:  update-internaldomains [-dh] [-a combine-file]
                               -f whitelist -s command
------------------------------------------------------------------------
  Version: $VERSION

  Summary:
           update-internaldomains is intended to be run from cron every
           fifteen minutes or so. -f and -s are required options. This
           script was originally written to retrieve a list of domains
           from vpopmail's 'vdominfo -n' command. However, it can be
           used with ANY command that returns a list of domains in the
           correct format (See -s syntax below).

           Possible -s commands might include: Billing apps, database
           retrieval scripts, radius query scripts, etc...

  How it works:    
           update-internaldomains executes the command specified by -s
           and saves it's output to a temporary file in the same
           directory as the file specified by -f.

           update-internaldomains then compares the whitelist specified
           by -f with the temp file it just created using 'diff -q'. If
           changes are found, update-internaldomains atomically replaces
           the whitelist specified by -f with the temporary file using 
           'mv'.

           NOTE: The 'mv' operation is only atomic if your system has
                 a POSIX rename() function, and the 'mv' command makes
                 use of it to overwrite single files.

  Command Line Options:

  -a combine-file
           If specified, combine-file is the full path to a flat file
           containing domain names, one per line, which you wish to
           COMBINE with the output of '-s command' BEFORE comparing
           and/or updating the whitelist specified by -f.

  -d       debug mode.

  -f whitelist
           This is the path to the whitelist you wish to write your 
           internal domain list to.

  -s command
           command you wish to run that will return a raw list of
           domains, one per line, in the following format:

           domain1.com
           domain2.com
           domain3.org
           etc...

  -h       print this usage report.

  Example: 

  update-internaldomains -f "/usr/local/vpopmail/.tmda/internaldomains" -s 
"/usr/local/vpopmail/bin/vdominfo -n"

  Return Codes:
           If update-internaldomains can not write to the directory in 
           which the file specified by -f resides, it exits nonzero.

           If update-internaldomains can not execute the command
           specified by -s, it immediately exits nonzero.

           If the 'mv' fails, update-internaldomains immediately exits
           nonzero.

           If anything else that update-internaldomains tries to execute
           fails, update-internaldomains will immediately exit nonzero.
------------------------------------------------------------------------\n

EOF
}






# -----------------------------------
# General Functions
# -----------------------------------

# save the last exit status
sub saveexitstatus()
{
        # Get exit status from last command.
        $last_error = $? >> 8;
}

# Get the last exit status
sub getexitstatus()
{
        # return exit status from last command.
        return $last_error;
}

# Print error message if bad exit status
sub dieifbadexit( $$ )
{
        my $badstatus=$_[0];  # the "bad" exit status
        my $message=$_[1];    # the message to print before exiting if the last exit 
status was "bad"

        # Check exit status.
        if ( getexitstatus() == $badstatus and getexitstatus() ne "") {
                print STDERR ($message);
                exit 1;
        }
}

# Print error message if bad exit status
sub dieifnotgoodexit( $$ )
{
        my $goodstatus=$_[0]; # the "good" exit status
        my $message=$_[1];    # the message to print before exiting if the last exit 
status was not the "good" exit status

        # Check exit status.
        if ( getexitstatus() != $goodstatus and getexitstatus() ne "") {
                print STDERR ($message);
                exit 1;
        }
}

# If debugging is turned on, print the message
sub ifdebugprint( $ )
{
        my $message=$_[0]; # the message to print
        # print debug info
        if ($debug) {
                print STDERR ($message);
        }
}




# -----------------------------------
# Handle command line arguments
# -----------------------------------

# Import Getopt::Std module
use Getopt::Std;

# we only take one option: -f
# -f has a single argument.
my $opt_string = 'hda:f:s:';

# get command line flags. If we recieve none, then we attempt to use defaults.
getopts( "$opt_string", \my %opt );

# print usage message if -h specified
usage() and exit if $opt{h};

# setup debug mode
$debug = 1 if $opt{d};
print STDERR "Debugging mode ON.\n" if $debug;

# set appropriate variables associated with -a
if ($opt{a}) {
        # if flat file does not exist, create it
        if ( ! -e $opt{a} ) {
                `touch "$opt{a}"`;

                # Get any bad exit status from 'rm'.
                saveexitstatus();

                # Check exit status.
                dieifnotgoodexit(0, "\nError: 'touch \"$opt{a}\"' failed!\n");

                # This code is only executed if the flat file was successfully created.
                ifdebugprint("whitelist created: $opt{a}\n");
        }
        
        die "$opt{a} is not readable." unless (-r $opt{a});

        $add_to_whitelist="$opt{a}";
        $do_combine=1;
}

# print debug info
ifdebugprint("\$add_to_whitelist=$add_to_whitelist\n");
ifdebugprint("\$do_combine=$do_combine\n");


# do checks on whitelist file and set $path_to_whitelist variable
if ($opt{f}) {
        if ($opt{f} == 1) {
                die "\n -f requires an argument.";
        }

        # if whitelist does not exist, create it
        if ( ! -e $opt{f} ) {
                `touch "$opt{f}"`;

                # Get any bad exit status from 'rm'.
                saveexitstatus();

                # Check exit status.
                dieifnotgoodexit(0, "\nError: 'touch \"$opt{f}\"' failed!\n");

                # This code is only executed if the whitelist file was successfully 
created.
                ifdebugprint("whitelist created: $opt{f}\n");
        }
        
        die "$opt{f} is not readable and writable." unless (-r $opt{f} and -w $opt{f});

        $path_to_whitelist="$opt{f}";

        # print debug info
        ifdebugprint("\$path_to_whitelist=$path_to_whitelist\n");
} else {
        usage();
        exit 1;
}

# do checks on command file and set $command variable
if ($opt{s}) {
        if ($opt{s} == 1) {
                die "\n -s requires an argument.";
        }
        
#       die "$opt{s} is not executable." unless (-x $opt{s});

        $command="$opt{s}";

        # print debug info
        ifdebugprint("\$command=$command\n");
} else {
        usage();
        exit 1;
}


# -----------------------------------
# Parse $path_to_whitelist for
# directory path.
# -----------------------------------

# get directory that whitelist lives in, then set $tmp_file variable
my $last_slash_loc = rindex ("$path_to_whitelist","/");

# if $path_to_whitelist contains JUST a filename and no path
if ($last_slash_loc == -1) {
        $base_whitelist_dir = ".";
} else {
        $base_whitelist_dir = substr ("$path_to_whitelist", 0, $last_slash_loc);
}

# build temp file path.
$tmp_file = $base_whitelist_dir . "/tmp";


# print debug info
ifdebugprint("\$tmp_file=$tmp_file\n");




# -----------------------------------
# Get command output
# -----------------------------------

# remove temp file if it exists
if ( -e "$tmp_file" ) {
        # print debug info
        ifdebugprint("'$tmp_file' exists.\n");

        `rm "$tmp_file"`;

        saveexitstatus();
        dieifnotgoodexit(0, "\"rm '$tmp_file'\" failed!");

        # print debug info
        ifdebugprint("\"rm '$tmp_file'\" successful!\n");
}

# Get any bad exit status from 'rm'.
saveexitstatus();

# Check exit status.
dieifnotgoodexit(0, "\nError: 'rm' failed to remove temp file!\n");

if ( -r "$add_to_whitelist" and $do_combine) {
        # define the string we wish to execute
        my $execstring="$command | cat - \"$add_to_whitelist\" | sort | uniq > 
\"$tmp_file\"";
        
        # execute our command pipe.
        `$execstring`;

        # Get any bad exit status from execution.
        saveexitstatus();

        # Check exit status and print error and exit if bad exit status found.
        dieifnotgoodexit(0, "\nError: `$execstring` failed!\n");
} else {
        # define the string we wish to execute
        my $execstring="$command | sort | uniq > \"$tmp_file\"";

        # execute our command pipe.
        `$execstring`;

        # Get any bad exit status from execution.
        saveexitstatus();

        # Check exit status.
        dieifnotgoodexit(0, "\nError: `$execstring` failed!\n");
}




# -----------------------------------
# Use 'diff -q' to compare the
# contents of our temp file with the
# contents of $path_to_whitelist
# -----------------------------------

`diff -q "$tmp_file" "$path_to_whitelist"`;

# Get any bad exit status from execution.
saveexitstatus();

#If 'diff -q' returns with an 'exit 2', then there has been an error.
dieifbadexit(2, "\nError: \"diff -q '$tmp_file' '$path_to_whitelist'\" failed!\n");



# -----------------------------------
# If the contents differ, then
# atomically update $path_to_whitelist
# Otherwise, simply 'exit 0;'
# -----------------------------------

#If 'diff -q' returns with an 'exit 1', the files do NOT match.
if ( getexitstatus() == 1 and getexitstatus() ne "") {
        # atomically overwrite $path_to_whitelist with $tmp_file
        `mv '$tmp_file' '$path_to_whitelist'`;

        # Get any bad exit status from execution.
        saveexitstatus();

        #If 'mv' returns nonzero, there was an error
        dieifnotgoodexit(0, "\nError: \"mv '$tmp_file' '$path_to_whitelist'\" 
failed!\n");
        
        # This point is only reached if 'mv' succeeded
        ifdebugprint("\"mv '$tmp_file' '$path_to_whitelist'\" successful!\n");
} else {
        # print debug info
        ifdebugprint("\"diff -q '$tmp_file' '$path_to_whitelist'\" indicates no update 
is necessary!\n");
}



# -----------------------------------
# Make sure the files we just touched
# are owned by $owner
# -----------------------------------

ifdebugprint("executing 'chown $owner \"$base_whitelist_dir\"/*'");

`chown $owner "$base_whitelist_dir"/*`;

saveexitstatus();
dieifnotgoodexit(0,"'chown $owner \"$base_whitelist_dir\"/*' failed!");

ifdebugprint("exiting happy.\n");

# If execution reaches this point, then chances are that all is well.
exit 0;

Index: ChangeLog
===================================================================
RCS file: /cvsroot/tmda/tmda/contrib/ChangeLog,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -r1.92 -r1.93
--- ChangeLog   20 Feb 2003 23:11:25 -0000      1.92
+++ ChangeLog   18 Mar 2003 21:50:24 -0000      1.93
@@ -1,3 +1,8 @@
+2003-03-18  Jason R. Mastaler  <[EMAIL PROTECTED]>
+
+       * update-internaldomains: New script from Jesse Guardiani.
+       Removed vipmap-to-authmap.
+
 2003-02-20  Jason R. Mastaler  <[EMAIL PROTECTED]>
 
        * tofmipd.init, tofmipd.sysconfig, cgi/tmda-cgi.conf: New support

--- vipmap-to-authmap DELETED ---

_______________________________________
tmda-cvs mailing list
http://tmda.net/lists/listinfo/tmda-cvs

Reply via email to