#!/usr/bin/perl # The Learning Online Network with CAPA # # apachereload - setuid script that reloads the apache daemon. # # $Id: apachereload,v 1.4 2005/10/31 16:13:45 albertel Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA 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. # # LON-CAPA 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 LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # use strict; # # This script is a setuid script that must be run as user www # it effectively just executes /etc/init.d/httpd reload. # causing the apache daemon to get HUP'd. The script is # run by lond after re-initing it's host information. $ENV{'PATH'}='/bin:/usr/bin:/usr/local/sbin:/home/httpd/perl'; # Nullify path # information delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # nullify potential taints my $command = "/etc/init.d/httpd reload"; use lib '/home/httpd/lib/perl/'; use LONCAPA::Configuration; my %perlvar= %{&LONCAPA::Configuration::read_conf('loncapa.conf')}; my $dist=`$perlvar{'lonDaemons'}/distprobe`; if ($dist =~ /^(suse|sles)/) { $command = "/etc/init.d/apache reload"; } # Do not print error messages my $noprint=1; print "In apachereload" unless $noprint; # ----------------------------- Make sure this process is running from user=www my $wwwid=getpwnam('www'); &disable_root_capability; if ($wwwid!=$>) { print("User ID mismatch. This program must be run as user 'www'\n") unless $noprint; exit 1; } # ----------------------------------- Start running script with www permissions &disable_root_capability; # --------------------------- Handle case of another apachereload process (locking) unless (&try_to_lock('/tmp/lock_apachereload')) { print "Error. Too many other simultaneous password change requests being ". "made.\n" unless $noprint; exit 4; } &enable_root_capability; ($>,$<)=(0,0); # Now run the reload: # system($command); # Remove the lock file. &disable_root_capability; unlink('/tmp/lock_apachereload'); exit 0; # ---------------------------------------------- have setuid script run as root sub enable_root_capability { if ($wwwid==$>) { ($<,$>)=($>,0); ($(,$))=($),0); } else { # root capability is already enabled } return $>; } # ----------------------------------------------- have setuid script run as www sub disable_root_capability { if ($wwwid==$<) { ($<,$>)=($>,$<); ($(,$))=($),$(); } else { # root capability is already disabled } } # ----------------------- make sure that another apachereload process isn't running sub try_to_lock { my ($lockfile)=@_; my $currentpid; my $lastpid; # Do not manipulate lock file as root if ($>==0) { return 0; } # Try to generate lock file. # Wait 3 seconds. If same process id is in # lock file, then assume lock file is stale, and # go ahead. If process id's fluctuate, try # for a maximum of 10 times. for (0..10) { if (-e $lockfile) { open(LOCK,"<$lockfile"); $currentpid=; close LOCK; if ($currentpid==$lastpid) { last; } sleep 3; $lastpid=$currentpid; } else { last; } if ($_==10) { return 0; } } open(LOCK,">$lockfile"); print LOCK $$; close LOCK; return 1; } =head1 NAME apachereload -setuid script to reload the apache web server. =head1 DESCRIPTION LON-CAPA - setuid script to reload the apache web server. =head1 README LON-CAPA setuid script to reload the apache web server. =head1 PREREQUISITES =head1 COREQUISITES =pod OSNAMES linux =pod SCRIPT CATEGORIES LONCAPA/Administrative =cut