Annotation of loncom/lciptables, revision 1.2
1.1 raeburn 1: #!/usr/bin/perl
2: #
3: # The Learning Online Network with CAPA
4: #
1.2 ! raeburn 5: # $Id: lciptables,v 1.1 2009/06/11 00:15:27 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');
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:
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>