Annotation of loncom/lciptables, revision 1.3

1.1       raeburn     1: #!/usr/bin/perl
                      2: #
                      3: # The Learning Online Network with CAPA
                      4: #
1.3     ! foxr        5: # $Id: lciptables,v 1.2 2010/03/25 01:28:34 raeburn Exp $
1.1       raeburn     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');
1.3     ! foxr       60: 
        !            61: if ($wwwid!=$<) {
1.1       raeburn    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
1.3     ! foxr       68: 
1.1       raeburn    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: 
1.3     ! foxr      100: 
1.1       raeburn   101: &EnableRoot();
                    102: 
1.2       raeburn   103: my @fw_chains = &LONCAPA::Firewall::get_fw_chains();
1.1       raeburn   104: my $iptables = &LONCAPA::Firewall::get_pathto_iptables();
                    105: my $firewall_result = 
1.2       raeburn   106:      &LONCAPA::Firewall::firewall_close_port($iptables,\@fw_chains,$lond_port,[$lond_port]);
1.1       raeburn   107: if ($firewall_result) {
                    108:     print "$firewall_result\n";
                    109: }
1.2       raeburn   110: my $firewall_result = &LONCAPA::Firewall::firewall_open_port($iptables,\@fw_chains,$lond_port,\%iphost,[$lond_port]);
1.1       raeburn   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>