version 1.11, 2004/10/20 09:30:57
|
version 1.20, 2007/08/22 19:53:22
|
Line 2
|
Line 2
|
|
|
# The Learning Online Network with CAPA |
# The Learning Online Network with CAPA |
# |
# |
|
# $Id$ |
|
# |
# Copyright Michigan State University Board of Trustees |
# Copyright Michigan State University Board of Trustees |
# |
# |
# This file is part of the LearningOnline Network with CAPA (LON-CAPA). |
# This file is part of the LearningOnline Network with CAPA (LON-CAPA). |
Line 41
|
Line 43
|
# NSCL |
# NSCL |
# Michigan State University8 |
# Michigan State University8 |
# East Lansing, MI 48824-1321 |
# East Lansing, MI 48824-1321 |
|
# |
# General flow of control: |
# General flow of control: |
# 1. Validate process state (must be run as www). |
# 1. Validate process state (must be run as www). |
# 2. Validate parameters: Need two parameters: |
# 2. Validate parameters: Need two parameters: |
Line 61
|
Line 63
|
# - internal - www:www/2775 |
# - internal - www:www/2775 |
# - local - www:www/2775 |
# - local - www:www/2775 |
# |
# |
|
# |
# |
# |
# Take a few precautions to be sure that we're not vulnerable to trojan |
# Take a few precautions to be sure that we're not vulnerable to trojan |
# horses and other fine issues: |
# horses and other fine issues: |
Line 69
|
Line 71
|
use strict; |
use strict; |
use Fcntl qw(:mode); |
use Fcntl qw(:mode); |
use DirHandle; |
use DirHandle; |
|
use POSIX; |
|
use lib '/home/httpd/lib/perl/'; |
|
use LONCAPA qw(:match); |
|
|
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/sbin:/home/httpd/perl'; |
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/sbin:/home/httpd/perl'; |
delete @ENV{qw{IFS CDPATH ENV BASH_ENV}}; |
delete @ENV{qw{IFS CDPATH ENV BASH_ENV}}; |
|
|
my $DEBUG = 0; # .nonzero -> Debug printing enabled. |
my $DEBUG = 1; # .nonzero -> Debug printing enabled. |
my $path_sep = "/"; # Unix like operating systems. |
my $path_sep = "/"; # Unix like operating systems. |
|
|
|
|
Line 132 if( $authentication ne "unix:" &&
|
Line 136 if( $authentication ne "unix:" &&
|
|
|
# Untaint the username. |
# Untaint the username. |
|
|
my $match = $username =~ /^(\w+)$/; |
my $match = $username =~ /^($match_username)$/; |
my $patt = $1; |
my $patt = $1; |
|
|
if($DEBUG) { |
if($DEBUG) { |
Line 144 my $safeuser = $patt;
|
Line 148 my $safeuser = $patt;
|
if($DEBUG) { |
if($DEBUG) { |
print("Save username = $safeuser \n"); |
print("Save username = $safeuser \n"); |
} |
} |
if(($username ne $safeuser) or ($safeuser!~/^[A-za-z]/)) { |
if($username ne $safeuser) { |
if($DEBUG) { |
if($DEBUG) { |
print("User name $username had illegal characters\n"); |
print("User name $username had illegal characters\n"); |
} |
} |
Line 154 if(($username ne $safeuser) or ($safeuse
|
Line 158 if(($username ne $safeuser) or ($safeuse
|
#untaint the base directory require that the dir contain only |
#untaint the base directory require that the dir contain only |
# alphas, / numbers or underscores, and end in /$safeuser |
# alphas, / numbers or underscores, and end in /$safeuser |
|
|
$dir =~ /(^([\w\/]+))/; |
|
|
|
my $dirtry1 = $1; |
|
|
|
$dir =~ /$\/$safeuser/; |
my ($allowed_dir) = ($dir =~ m{(^([/]|$match_username)+)}); |
my $dirtry2 = $1; |
|
|
|
if(($dirtry1 ne $dir) or ($dirtry2 ne $dir)) { |
my $has_correct_end = ($dir =~ m{/\Q$safeuser\E$}); |
|
|
|
if(($allowed_dir ne $dir) or (!$has_correct_end)) { |
if ($DEBUG) { |
if ($DEBUG) { |
print("Directory $dir is not a valid home for $safeuser\n"); |
print("Directory $dir is not a valid home for $safeuser\n"); |
} |
} |
exit 5; |
exit 5; |
} |
} |
|
|
|
|
# As root, create the directory. |
# As root, create the directory. |
|
|
my $homedir = $dirtry1; |
my $homedir = $allowed_dir; |
my $fulldir = $homedir."/public_html"; |
my $fulldir = $homedir."/public_html"; |
|
|
if($DEBUG) { |
if($DEBUG) { |
print("Full directory path is: $fulldir \n"); |
print("Full directory path is: $fulldir \n"); |
} |
} |
if(!( -e $dirtry1)) { |
if(!( -e $homedir)) { |
if($DEBUG) { |
if($DEBUG) { |
print("User's home directory $dirtry1 does not exist\n"); |
print("User's home directory $homedir does not exist\n"); |
} |
} |
if ($authentication eq "unix:") { |
if ($authentication eq "unix:") { |
exit 6; |
exit 6; |
} |
} |
} |
} |
|
if ($authentication eq "unix:") { |
|
# check whether group $safeuser exists. |
|
my $usergroups = `id -nG $safeuser`; |
|
if (! grep /^$safeuser$/, split(/\s+/,$usergroups)) { |
|
if($DEBUG) { |
|
print("Group \"$safeuser\" does not exist or $safeuser is not a member of that group.\n"); |
|
} |
|
exit 7; |
|
} |
|
} |
|
|
|
|
|
|
&EnableRoot; |
&EnableRoot; |
|
|
|
# If authentication is internal and the top level directory exists |
|
# give it the right permissions (in case this is a modification. |
|
|
|
if ($authentication eq "internal:") { |
|
chmod(0711, $homedir); # so www can enter ~/public_html. |
|
} |
|
|
&System("/bin/mkdir -p $fulldir") unless (-e $fulldir); |
&System("/bin/mkdir -p $fulldir") unless (-e $fulldir); |
unless(-e $fulldir."/index.html") { |
unless(-e $fulldir."/index.html") { |
open OUT,">".$fulldir."/index.html"; |
open OUT,">".$fulldir."/index.html"; |
Line 214 END
|
Line 236 END
|
close OUT; |
close OUT; |
} |
} |
|
|
&System("/bin/chmod 02775 $fulldir"); |
&System("/bin/chmod 02770 $fulldir"); |
&System("/bin/chmod 0775 $fulldir"."/index.html"); |
&System("/bin/chmod 0770 $fulldir"."/index.html"); |
|
|
|
|
# Based on the authentiation mode, set the ownership of the directory. |
# Based on the authentiation mode, set the ownership of the directory. |
|
|
if($authentication eq "unix:") { # Unix mode authentication... |
if($authentication eq "unix:") { # Unix mode authentication... |
&System("/bin/chown -R $safeuser".":".$safeuser." ".$fulldir); |
print "Unix auth\n"; |
|
&System("/bin/chown -R $safeuser:$safeuser"." ".$fulldir); |
&JoinGroup($safeuser); |
&JoinGroup($safeuser); |
} else { |
} else { |
# Internal, Kerberos, and Local authentication are for users |
# Internal, Kerberos, and Local authentication are for users |
Line 237 if($authentication eq "unix:") { # Unix
|
Line 260 if($authentication eq "unix:") { # Unix
|
# user's home directory that can reset ownerships and permissions |
# user's home directory that can reset ownerships and permissions |
# back the way the used to be. |
# back the way the used to be. |
|
|
&write_restore_script($homedir); |
# This can take long enough for lond to time out, so we'll do it |
|
# in a separate process that we'll not wait for. |
&System("/bin/chown -R root:root ".$homedir); |
# |
|
my $fpid = fork; |
|
if($fpid) { |
|
&DisableRoot; |
|
exit 0; |
|
} else { |
|
print "Forked\n"; |
|
POSIX::setsid(); # Disassociate from parent. |
|
print "Separate session\n"; |
|
&write_restore_script($homedir); |
|
print "Restore script written\n"; |
|
&System("/bin/chown -R root:root ".$homedir); |
|
&System("/bin/chown -R www:www ".$fulldir); |
|
print "Exiting\n"; |
|
exit 0; |
|
} |
|
} else { |
|
&System("/bin/chown -R www:www ".$fulldir); |
} |
} |
&System("/bin/chown -R www:www ".$fulldir); |
|
} |
} |
&DisableRoot; |
&DisableRoot; |
|
|
Line 283 sub DisableRoot {
|
Line 323 sub DisableRoot {
|
print("Disable root: id = ".$>."\n"); |
print("Disable root: id = ".$>."\n"); |
} |
} |
} |
} |
|
# |
|
# Join the www user to the user's group. |
|
# we must be running with euid as root at this time. |
|
# |
sub JoinGroup { |
sub JoinGroup { |
my $usergroup = shift; |
my $usergroup = shift; |
|
|
Line 302 sub JoinGroup {
|
Line 345 sub JoinGroup {
|
} |
} |
exit 6; |
exit 6; |
} |
} |
|
if (-e '/var/run/httpd.pid') { |
|
open(PID,'/var/run/httpd.pid'); |
|
my $pid=<PID>; |
|
close(PID); |
|
my ($safepid) = $pid=~ /(\d+)/; |
|
$pid = $safepid; |
|
if ($pid) { |
|
my $status = system("kill -USR1 $safepid"); |
|
} |
|
} |
} |
} |
|
|
|
|