[LON-CAPA-cvs] cvs: loncom / lcuseradd
foxr
lon-capa-cvs@mail.lon-capa.org
Thu, 05 Aug 2004 10:56:55 -0000
This is a MIME encoded message
--foxr1091703415
Content-Type: text/plain
foxr Thu Aug 5 06:56:55 2004 EDT
Modified files:
/loncom lcuseradd
Log:
Add capability (optional for compatibilty with existing code)
to write the error code to a file passed in to lcuseradd. NOte
that the file must be in a directory that is writable by www
I recommend /tmp -- and that the reader of that file unlink it.
This is my way to get around the fact that runing lcuseradd on a pipe
prevents you from getting the exit status of the program, which in turn
prevents the loncapa UI from knowing that adding a user has actually failed!
--foxr1091703415
Content-Type: text/plain
Content-Disposition: attachment; filename="foxr-20040805065655.txt"
Index: loncom/lcuseradd
diff -u loncom/lcuseradd:1.25 loncom/lcuseradd:1.26
--- loncom/lcuseradd:1.25 Mon Feb 3 13:03:52 2003
+++ loncom/lcuseradd Thu Aug 5 06:56:55 2004
@@ -14,7 +14,7 @@
# o LonCapa will add it if/when the user is granted an Author
# role.
#
-# $Id: lcuseradd,v 1.25 2003/02/03 18:03:52 harris41 Exp $
+# $Id: lcuseradd,v 1.26 2004/08/05 10:56:55 foxr Exp $
###
###############################################################################
@@ -50,11 +50,20 @@
# www becomes a member of this user group.
# -------------- Invoking script (standard input versus command-line arguments)
+# Otherwise sensitive information will be available to ps-ers for
+# a small but exploitable time window.
#
# Standard input (STDIN) usage
# First line is USERNAME
# Second line is PASSWORD
# Third line is PASSWORD
+# Fouth line is the name of a file to which an error code will be written.
+# If the fourth line is omitted, no error file will be written.
+# In either case, the program Exits with the code as its Exit status.
+# The error file will just be a single line containing an
+# error code.
+#
+#
#
# Command-line arguments [USERNAME] [PASSWORD] [PASSWORD]
# Yes, but be very careful here (don't pass shell commands)
@@ -78,9 +87,9 @@
# ---------------------------------- Example usage inside another piece of code
# Usage within code
#
-# $exitcode=
+# $Exitcode=
# system("/home/httpd/perl/lcuseradd","NAME","PASSWORD1","PASSWORD2")/256;
-# print "uh-oh" if $exitcode;
+# print "uh-oh" if $Exitcode;
# ---------------------------------------------------- Description of functions
# enable_root_capability() : have setuid script run as root
@@ -88,7 +97,7 @@
# try_to_lock() : make sure that another lcpasswd process isn't running
# ------------------------------------------------------------------ Exit codes
-# These are the exit codes.
+# These are the Exit codes.
# ( (0,"ok"),
# (1,"User ID mismatch. This program must be run as user 'www'"),
# (2,"Error. This program needs 3 command-line arguments (username, ".
@@ -106,6 +115,7 @@
# (12,"Error. Something went wrong with the addition of user ".
# "\"$safeusername\"."),
# (13,"Error. Password mismatch."),
+# (14, "Error filename is invalid")
# ------------------------------------------------------------- Initializations
# Security
@@ -116,6 +126,10 @@
# Do not print error messages.
my $noprint=1;
+# Error file:
+
+my $error_file; # This is either the error file name or undef.
+
print "In lcuseradd\n" unless $noprint;
# ----------------------------- Make sure this process is running from user=www
@@ -124,7 +138,7 @@
if ($wwwid!=$>) {
print("User ID mismatch. This program must be run as user 'www'\n")
unless $noprint;
- exit 1;
+ &Exit(1);
}
# ----------------------------------- Start running script with www permissions
@@ -134,32 +148,32 @@
unless (&try_to_lock("/tmp/lock_lcpasswd")) {
print "Error. Too many other simultaneous password change requests being ".
"made.\n" unless $noprint;
- exit 4;
+ &Exit(4);
}
# ------- Error-check input, need 3 values (user name, password 1, password 2).
my @input;
-if (@ARGV==3) {
+if (@ARGV>=3) {
@input=@ARGV;
}
elsif (@ARGV) {
- print("Error. This program needs 3 command-line arguments (username, ".
- "password 1, password 2).\n") unless $noprint;
+ print("Error. This program needs at least 3 command-line arguments (username, ".
+ "password 1, password 2 [errorfile]).\n") unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 2;
+ &Exit(2);
}
else {
@input=<>;
- if (@input!=3) {
- print("Error. Three lines should be entered into standard input.\n")
+ if (@input < 3) {
+ print("Error. At least three lines should be entered into standard input.\n")
unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 3;
+ &Exit(3);
}
foreach (@input) {chomp;}
}
-my ($username,$password1,$password2)=@input;
+my ($username,$password1,$password2, $error_file)=@input;
print "Username = ".$username."\n" unless $noprint;
$username=~/^(\w+)$/;
print "Username after substitution - ".$username unless $noprint;
@@ -170,22 +184,52 @@
print "Error. The user name specified $username $safeusername has invalid characters.\n"
unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 9;
+ &Exit(9);
}
my $pbad=0;
foreach (split(//,$password1)) {if ((ord($_)<32)||(ord($_)>126)){$pbad=1;}}
foreach (split(//,$password2)) {if ((ord($_)<32)||(ord($_)>126)){$pbad=1;}}
if ($pbad) {
- print "Error. A password entry had an invalid character.\n";
+ print "Error. A password entry had an invalid character.\n" unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 10;
+ &Exit(10);
}
+#
+# Safe the filename. For our case, it must only have alpha, numeric, period
+# and path sparators..
+#
+
+print "Error file is $error_file \n" unless $noprint;
+
+if($error_file) {
+ if($error_file =~ /^([(\w)(\d)\.\/]+)$/) {
+ print "Error file matched pattern $error_file : $1\n" unless $noprint;
+ my $safe_error_file = $1; # Untainted I think.
+ print "Error file after transform $safe_error_file\n"
+ unless $noprint;
+ if($error_file == $safe_error_file) {
+ $error_file = $safe_error_file; # untainted error_file.
+ } else {
+ $error_file ="";
+ print "Invalid error filename\n" unless $noprint;
+ Exit(14);
+ }
+
+ }
+ else {
+ $error_file="";
+ print "Invalid error filename\n" unless $noprint;
+ Exit(14);
+ }
+}
+
+
# -- Only add user if we can create a brand new home directory (/home/username)
if (-e "/home/$safeusername") {
print "Error. User already exists.\n" unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 11;
+ &Exit(11);
}
# -- Only add user if the two password arguments match.
@@ -193,7 +237,7 @@
if ($password1 ne $password2) {
print "Error. Password mismatch.\n" unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 13;
+ &Exit(13);
}
print "enabling root\n" unless $noprint;
# ---------------------------------- Start running script with root permissions
@@ -209,11 +253,11 @@
"\"$safeusername\".\n" unless $noprint;
print "Final status of useradd = $status";
unlink('/tmp/lock_lcpasswd');
- exit 12;
+ &Exit(12);
}
print "Done adding user\n" unless $noprint;
# Make www a member of that user group.
-my $groups=`/usr/bin/groups www` or exit(6);
+my $groups=`/usr/bin/groups www` or &Exit(6);
chomp $groups; $groups=~s/^\S+\s+\:\s+//;
my @grouplist=split(/\s+/,$groups);
my @ugrouplist=grep {!/www|$safeusername/} @grouplist;
@@ -223,7 +267,7 @@
print "Error. Could not make www a member of the group ".
"\"$safeusername\".\n" unless $noprint;
unlink('/tmp/lock_lcpasswd');
- exit 6;
+ &Exit(6);
}
# ---------------------------------------------------------------- Set password
@@ -242,8 +286,8 @@
print OUT "\n";
close OUT;
if ($?) {
- print "abnormal exit from close lcpasswd\n" unless $noprint;
- exit 8;
+ print "abnormal Exit from close lcpasswd\n" unless $noprint;
+ &Exit(8);
}
($>,$<)=($wwwid,0);
&enable_root_capability;
@@ -286,9 +330,9 @@
}
}
# -------------------------------------------------------- Exit script
-print "lcuseradd exiting\n" unless $noprint;
+print "lcuseradd Exiting\n" unless $noprint;
&disable_root_capability;
-exit 0;
+&Exit(0);
# ---------------------------------------------- Have setuid script run as root
sub enable_root_capability {
@@ -350,6 +394,22 @@
close LOCK;
return 1;
}
+#-------------------------- Exit...
+#
+# Write the file if the error_file is defined. Regardless
+# Exit with the status code.
+#
+sub Exit {
+ my ($code) = @_; # Status code.
+
+ print "Exiting with status $code error file is $error_file\n" unless $noprint;
+ if($error_file) {
+ open(FH, ">$error_file");
+ print FH "$code\n";
+ close(FH);
+ }
+ exit $code;
+}
=head1 NAME
--foxr1091703415--