Annotation of loncom/lciptables, revision 1.1

1.1     ! raeburn     1: #!/usr/bin/perl
        !             2: #
        !             3: # The Learning Online Network with CAPA
        !             4: #
        !             5: # $Id: lciptables,v 1.1 2009/06/11 00:55:48 raeburn Exp $
        !             6: #
        !             7: # Copyright Michigan State University Board of Trustees
        !             8: #
        !             9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
        !            10: #
        !            11: # LON-CAPA is free software; you can redistribute it and/or modify
        !            12: # it under the terms of the GNU General Public License as published by
        !            13: # the Free Software Foundation; either version 2 of the License, or
        !            14: # (at your option) any later version.
        !            15: #
        !            16: # LON-CAPA is distributed in the hope that it will be useful,
        !            17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            19: # GNU General Public License for more details.
        !            20: #
        !            21: # You should have received a copy of the GNU General Public License
        !            22: # along with LON-CAPA; if not, write to the Free Software
        !            23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            24: #
        !            25: # /home/httpd/html/adm/gpl.txt
        !            26: #
        !            27: # http://www.lon-capa.org/
        !            28: #
        !            29: #  lciptables - LONC-CAPA setuid script to:
        !            30: #              o use iptables commands to update Firewall rules for current
        !            31: #                list of IPs for LON-CAPA hosts in server's cluster.
        !            32: #
        !            33: 
        !            34: use strict;
        !            35: use lib '/home/httpd/lib/perl/';
        !            36: use LONCAPA::Firewall;
        !            37: 
        !            38: # ------------------------------------------------------------------ Exit codes
        !            39: # Exit codes.
        !            40: # ( (0,"ok"),
        !            41: # (1,"User ID mismatch.  This program must be run as user 'www'"),
        !            42: # (2,"Missing argument: Usage: this script takes one argument - ".
        !            43: # " the name of a file in /home/httpd/perl/tmp containing IP addresses."),
        !            44: # (3,"Missing IP addresses file. The file containing IP addresses is missing."),
        !            45: # (4,"Error. Only one lciptables script can run at any time."),
        !            46: #
        !            47: # ------------------------------------------------------------- Initializations
        !            48: # Security
        !            49: $ENV{'PATH'}='/bin/:/usr/bin:/usr/local/sbin:/home/httpd/perl'; # Nullify path
        !            50:                                                                 # information
        !            51: delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # nullify potential taints
        !            52: 
        !            53: # Do not print error messages.
        !            54: my $noprint=1;
        !            55: 
        !            56: print "In lciptables\n" unless $noprint;
        !            57: 
        !            58: # ----------------------------- Make sure this process is running from user=www
        !            59: my $wwwid=getpwnam('www');
        !            60: &DisableRoot;
        !            61: if ($wwwid!=$>) {
        !            62:     print("User ID mismatch.  This program must be run as user 'www'\n")
        !            63:         unless $noprint;
        !            64:     &Exit(1);
        !            65: }
        !            66: 
        !            67: # ----------------------------------- Retrieve IP addreses for hosts in cluster
        !            68: &DisableRoot;
        !            69: 
        !            70: my %iphost;
        !            71: if (@ARGV != 1) {
        !            72:     print("Error. this script takes one argument - the name of a file in /home/httpd/perl/tmp containing IP addresses.\n") unless $noprint;
        !            73:     &Exit(2);
        !            74: }
        !            75: my $tmpfile = $ARGV[0];
        !            76: if (-e $tmpfile) {
        !            77:     if (open(my $fh,"<$tmpfile")) {
        !            78:         while(<$fh>) {
        !            79:             chomp();
        !            80:             $iphost{$_} = 1;
        !            81:         }
        !            82:         close($fh);
        !            83:     } else {
        !            84:        &Exit(3);  
        !            85:     }
        !            86: } else {
        !            87:     print "Error. File containing IP addresses of hosts in cluster does not exist\n" unless $noprint;
        !            88:     &Exit(3);
        !            89: }
        !            90: 
        !            91: # --------------------------- Handle case of another lciptables process (locking)
        !            92: unless (&try_to_lock("/tmp/lock_lciptables")) {
        !            93:     print "Error. Too many other simultaneous iptables manipulation requests being ".
        !            94:         "made.\n" unless $noprint;
        !            95:     &Exit(4);
        !            96: }
        !            97: 
        !            98: my $lond_port = &LONCAPA::Firewall::get_lond_port();
        !            99: 
        !           100: ($>,$<)=($wwwid,0);
        !           101: &EnableRoot();
        !           102: 
        !           103: my $fw_chain = &LONCAPA::Firewall::get_fw_chain();
        !           104: my $iptables = &LONCAPA::Firewall::get_pathto_iptables();
        !           105: my $firewall_result = 
        !           106:      &LONCAPA::Firewall::firewall_close_port($iptables,$fw_chain,$lond_port,[$lond_port]);
        !           107: if ($firewall_result) {
        !           108:     print "$firewall_result\n";
        !           109: }
        !           110: my $firewall_result = &LONCAPA::Firewall::firewall_open_port($iptables,$fw_chain,$lond_port,\%iphost,[$lond_port]);
        !           111: if ($firewall_result) {
        !           112:     print "$firewall_result\n";
        !           113: }
        !           114: 
        !           115: # -------------------------------------------------------- Exit script
        !           116: print "lciptables Exiting\n" unless $noprint;
        !           117: &DisableRoot;
        !           118: unlink('/tmp/lock_lciptables');
        !           119: &Exit(0);
        !           120: 
        !           121: 
        !           122: sub EnableRoot {
        !           123:     if ($wwwid==$>) {
        !           124:         ($<,$>)=($>,$<);
        !           125:         ($(,$))=($),$();
        !           126:     }
        !           127:     else {
        !           128:         # root capability is already enabled
        !           129:     }
        !           130:     return $>;
        !           131: }
        !           132: 
        !           133: sub DisableRoot {
        !           134:     if ($wwwid==$<) {
        !           135:         ($<,$>)=($>,$<);
        !           136:         ($(,$))=($),$();
        !           137:     }
        !           138:     else {
        !           139:         # root capability is already disabled
        !           140:     }
        !           141: }
        !           142: 
        !           143: sub try_to_lock {
        !           144:     my ($lockfile)=@_;
        !           145:     my $currentpid;
        !           146:     my $lastpid;
        !           147:     # Do not manipulate lock file as root
        !           148:     if ($>==0) {
        !           149:         return 0;
        !           150:     }
        !           151:     # Try to generate lock file.
        !           152:     # Wait 3 seconds.  If same process id is in
        !           153:     # lock file, then assume lock file is stale, and
        !           154:     # go ahead.  If process id's fluctuate, try
        !           155:     # for a maximum of 10 times.
        !           156:     for (0..10) {
        !           157:         if (-e $lockfile) {
        !           158:             open(LOCK,"<$lockfile");
        !           159:             $currentpid=<LOCK>;
        !           160:             close LOCK;
        !           161:             if ($currentpid==$lastpid) {
        !           162:                 last;
        !           163:             }
        !           164:             sleep 3;
        !           165:             $lastpid=$currentpid;
        !           166:         } else {
        !           167:             last;
        !           168:         }
        !           169:         if ($_==10) {
        !           170:             return 0;
        !           171:         }
        !           172:     }
        !           173:     open(LOCK,">$lockfile");
        !           174:     print LOCK $$;
        !           175:     close LOCK;
        !           176:     return 1;
        !           177: }
        !           178: 
        !           179: sub Exit {
        !           180:     my ($code) = @_;
        !           181:     &DisableRoot();
        !           182:     print "Exiting with status $code\n" unless $noprint;
        !           183:     exit $code;
        !           184: }
        !           185: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>