[LON-CAPA-cvs] cvs: loncom / lcinstallfile
foxr
foxr@source.lon-capa.org
Tue, 24 Feb 2009 11:52:03 -0000
foxr Tue Feb 24 11:52:03 2009 EDT
Modified files:
/loncom lcinstallfile
Log:
Debugged - this installs a table file (setuid) on bahalf of the lond.
Index: loncom/lcinstallfile
diff -u loncom/lcinstallfile:1.1 loncom/lcinstallfile:1.2
--- loncom/lcinstallfile:1.1 Fri Feb 20 11:26:34 2009
+++ loncom/lcinstallfile Tue Feb 24 11:52:03 2009
@@ -24,8 +24,8 @@
#
# 2/17/2009 - Ron FOx
# $Id:
-
-http://www.lon-capa.org/
+#
+# http://www.lon-capa.org/
#
# This file is a setuid script that allows lond or other www programs to install
# a file in the lon capa table directory.
@@ -41,12 +41,15 @@
use strict;
-my $LONCAPAHOME = '/home/httpd; # Adjust if loncapa isn't installed here.
+my $LONCAPAHOME = '/home/httpd'; # Adjust if loncapa isn't installed here.
-use lib "$LONCAPAHOME/perl/lib";
+use lib "/home/httpd/lib/perl";
use LONCAPA;
use LONCAPA::Configuration;
use IO::File;
+use File::Copy;
+
+
#
# Exit codes:
@@ -57,8 +60,9 @@
# 4 - source_file_name does not exist.
# 5 - destination file does not exist (not allowed to create new files).
# 6 - Some file operation failed.
+# 7 - Invalid table filename.
#
-$noprint = 0;
+my $noprint = 0;
#
# Ensure we are www:
#
@@ -76,21 +80,37 @@
#
my $argc = scalar(@ARGV);
if ($argc != 2) {
- print("Usage: lcinstallfile sourcepath destfile\n") unlesss $noprint;
+ print("Usage: lcinstallfile sourcepath destfile\n") unless $noprint;
exit 2;
}
-my $sorcepath = $ARGV[0];
+my $sourcepath = $ARGV[0];
my $destfile = $ARGV[1];
+
+
# Ensure the source file exists, and root can write it.:
-&enable_root_capability;
+# since this is a setuid program, the sourcepath and destfile
+# must be pattern extracted else they are considered insecure and
+# therefore not validated.
+# loncapa table files are all of the form.
+# something.tab where something is all letters and _'s.
+#
+if ($sourcepath =~ /^(\w+\.tab)$/) {
+ $sourcepath = $1;
+} else {
+ print ("Invalid characters in filename $sourcepath \n") unless $noprint;
+ exit 7;
+}
+
+
if (! -r $sourcepath) {
- &disable_root_capability;
print("File $sourcepath either does not exist or cannot be read") unless $noprint;
exit 4;
}
+&enable_root_capability;
+
#
# Figure out where the lontab directory is and create the destinationfile name:
#
@@ -98,10 +118,20 @@
# so ensure that the final destination file actually exists.
#
my $config_vars = LONCAPA::Configuration::read_conf('loncapa.conf');
-my %config = %{$configvars};
+my %config = %{$config_vars};
my $tab_dir = $config{'lonTabDir'};
-my $final_file = $tabdir.'/'.$destfile;
+my $final_file = $tab_dir.'/'.$destfile;
+
+#
+# Now sanitize the final file:
+
+if ($final_file =~ /^([\w\/]+\.tab)$/) {
+ $final_file = $1;
+} else {
+ print ("$final_file failed regexp match\n") unless $noprint;
+ exit 7;
+}
if (! -w $final_file) {
&disable_root_capability;
@@ -111,16 +141,17 @@
#
# Copy the destination file to a backup:
#
-if (!File::Copy($final_file, $final_file.'.backup')) {
+if (!copy($final_file, $final_file.'.backup')) {
&disable_root_capability;
print ("Failed to create backup copy of $final_file\n") unless $noprint;
exit 6;
}
+&enable_root_capability;
# Install the new file to a temp file in the same dir so it can be mv'd in place
# this prevents the possibility we wind up with a partial file.:
-if (!File::Copy($sourcepath, $final_file.'.new')) {
+if (!copy($sourcepath, $final_file.'.new')) {
&disable_root_capability;
print("Failed to copy $sourcepath to a tempfile\n") unless $noprint;
exit 6;
@@ -128,24 +159,25 @@
#
# Move the temp file to the final file
#
-if (!rename($final_path.'.new', $final_path)) {
+if (!rename($final_file.'.new', $final_file)) {
&disable_root_capability;
- print ("Failed to move installed file $final_path.new to final resting place\n")
+ print ("Failed to move installed file $final_file.new to final resting place\n")
unless $noprint;
exit 6;
}
# Ready to exit with success
-&disble_root_capability;
-print ("$sourcepaht installed to $final_file\n") unless $noprint;
+&disable_root_capability;
+print ("$sourcepath installed to $final_file\n") unless $noprint;
exit 0;
+
#-------------------------------------------------------------------------
#
# subs that control the setuid-edness of the program.
-# ---------------------------------------------- have setuid script run as root
+# have setuid script run as root
sub enable_root_capability {
if ($wwwid==$>) {
($<,$>)=($>,0);
@@ -157,7 +189,7 @@
return $>;
}
-# ----------------------------------------------- have setuid script run as www
+# have setuid script run as www
sub disable_root_capability {
if ($wwwid==$<) {
($<,$>)=($>,$<);