[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==$<) {
 	($<,$>)=($>,$<);