--- loncom/lond 2009/10/09 12:36:10 1.410.2.2 +++ loncom/lond 2009/03/03 12:08:07 1.412 @@ -2,7 +2,7 @@ # The LearningOnline Network # lond "LON Daemon" Server (port "LOND" 5663) # -# $Id: lond,v 1.410.2.2 2009/10/09 12:36:10 raeburn Exp $ +# $Id: lond,v 1.412 2009/03/03 12:08:07 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -54,12 +54,12 @@ use LONCAPA::lonssl; use Fcntl qw(:flock); use Apache::lonnet; -my $DEBUG = 0; # Non zero to enable debug log entries. +my $DEBUG = 1; # Non zero to enable debug log entries. my $status=''; my $lastlog=''; -my $VERSION='$Revision: 1.410.2.2 $'; #' stupid emacs +my $VERSION='$Revision: 1.412 $'; #' stupid emacs my $remoteVERSION; my $currenthostid="default"; my $currentdomainid; @@ -142,6 +142,16 @@ my @adderrors = ("ok", "lcuseradd Password mismatch"); +# This array are the errors from lcinstallfile: + +my @installerrors = ("ok", + "Initial user id of client not that of www", + "Usage error, not enough command line arguments", + "Source file name does not exist", + "Destination file name does not exist", + "Some file operation failed", + "Invalid table filename." + ); # # Statistics that are maintained and dislayed in the status line. @@ -398,6 +408,7 @@ sub isClient { # sub ReadManagerTable { + &Debug("Reading manager table"); # Clean out the old table first.. foreach my $key (keys %managers) { @@ -520,11 +531,9 @@ sub AdjustHostContents { } # # InstallFile: Called to install an administrative file: -# - The file is created with .tmp -# - The .tmp file is then mv'd to -# This lugubrious procedure is done to ensure that we are never without -# a valid, even if dated, version of the file regardless of who crashes -# and when the crash occurs. +# - The file is created int a temp directory called .tmp +# - lcinstall file is called to install the file. +# since the web app has no direct write access to the table directory # # Parameters: # Name of the file @@ -532,11 +541,16 @@ sub AdjustHostContents { # Return: # nonzero - success. # 0 - failure and $! has an errno. +# Assumptions: +# File installtion is a relatively infrequent # sub InstallFile { my ($Filename, $Contents) = @_; - my $TempFile = $Filename.".tmp"; +# my $TempFile = $Filename.".tmp"; + my $exedir = $perlvar{'lonDaemons'}; + my $tmpdir = $exedir.'/tmp/'; + my $TempFile = $tmpdir."TempTableFile.tmp"; # Open the file for write: @@ -550,11 +564,27 @@ sub InstallFile { print $fh ($Contents); $fh->close; # In case we ever have a filesystem w. locking - chmod(0660, $TempFile); + chmod(0664, $TempFile); # Everyone can write it. - # Now we can move install the file in position. - - move($TempFile, $Filename); + # Use lcinstall file to put the file in the table directory... + + &Debug("Opening pipe to $exedir/lcinstallfile $TempFile $Filename"); + my $pf = IO::File->new("| $exedir/lcinstallfile $TempFile $Filename > $exedir/logs/lcinstallfile.log"); + close $pf; + my $err = $?; + &Debug("Status is $err"); + if ($err != 0) { + my $msg = $err; + if ($err < @installerrors) { + $msg = $installerrors[$err]; + } + &logthis("Install failed for table file $Filename : $msg"); + return 0; + } + + # Remove the temp file: + + unlink($TempFile); return 1; } @@ -562,8 +592,13 @@ sub InstallFile { # # ConfigFileFromSelector: converts a configuration file selector -# (one of host or domain at this point) into a -# configuration file pathname. +# into a configuration file pathname. +# It's probably no longer necessary to preserve +# special handling of hosts or domain as those +# files have been superceded by dns_hosts, dns_domain. +# The default action is just to prepend the directory +# and append .tab +# # # Parameters: # selector - Configuration file selector. @@ -580,7 +615,7 @@ sub ConfigFileFromSelector { } elsif ($selector eq "domain") { $tablefile = $tabledir."domain.tab"; } else { - return undef; + $tablefile = $tabledir.$selector.'.tab'; } return $tablefile; @@ -603,6 +638,7 @@ sub ConfigFileFromSelector { sub PushFile { my $request = shift; my ($command, $filename, $contents) = split(":", $request, 3); + &Debug("PushFile"); # At this point in time, pushes for only the following tables are # supported: @@ -619,20 +655,7 @@ sub PushFile { if(! (defined $tablefile)) { return "refused"; } - # - # >copy< the old table to the backup table - # don't rename in case system crashes/reboots etc. in the time - # window between a rename and write. - # - my $backupfile = $tablefile; - $backupfile =~ s/\.tab$/.old/; - if(!CopyFile($tablefile, $backupfile)) { - &logthis(' CopyFile from '.$tablefile." to ".$backupfile." failed "); - return "error:$!"; - } - &logthis(' Pushfile: backed up ' - .$tablefile." to $backupfile"); - + # If the file being pushed is the host file, we adjust the entry for ourself so that the # IP will be our current IP as looked up in dns. Note this is only 99% good as it's possible # to conceive of conditions where we don't have a DNS entry locally. This is possible in a @@ -645,6 +668,7 @@ sub PushFile { # Install the new file: + &logthis("Installing new $tablefile contents:\n$contents"); if(!InstallFile($tablefile, $contents)) { &logthis(' Pushfile: unable to install ' .$tablefile." $! "); @@ -1198,7 +1222,7 @@ sub user_authorization_type { # a reply is written to the client. sub push_file_handler { my ($cmd, $tail, $client) = @_; - + &Debug("In push file handler"); my $userinput = "$cmd:$tail"; # At this time we only know that the IP of our partner is a valid manager @@ -1206,7 +1230,8 @@ sub push_file_handler { # spoofing). my $cert = &GetCertificate($userinput); - if(&ValidManager($cert)) { + if(&ValidManager($cert)) { + &Debug("Valid manager: $client"); # Now presumably we have the bona fides of both the peer host and the # process making the request. @@ -1215,6 +1240,7 @@ sub push_file_handler { &Reply($client, \$reply, $userinput); } else { + &logthis("push_file_handler $client is not valid"); &Failure( $client, "refused\n", $userinput); } return 1; @@ -1781,9 +1807,8 @@ sub change_password_handler { # npass - New password. # context - Context in which this was called # (preferences or reset_by_email). - # lonhost - HostID of server where request originated - my ($udom,$uname,$upass,$npass,$context,$lonhost)=split(/:/,$tail); + my ($udom,$uname,$upass,$npass,$context)=split(/:/,$tail); $upass=&unescape($upass); $npass=&unescape($npass); @@ -1792,13 +1817,9 @@ sub change_password_handler { # First require that the user can be authenticated with their # old password unless context was 'reset_by_email': - my ($validated,$failure); + my $validated; if ($context eq 'reset_by_email') { - if ($lonhost eq '') { - $failure = 'invalid_client'; - } else { - $validated = 1; - } + $validated = 1; } else { $validated = &validate_user($udom, $uname, $upass); } @@ -1812,11 +1833,8 @@ sub change_password_handler { $salt=substr($salt,6,2); my $ncpass=crypt($npass,$salt); if(&rewrite_password_file($udom, $uname, "internal:$ncpass")) { - my $msg="Result of password change for $uname: pwchange_success"; - if ($lonhost) { - $msg .= " - request originated from: $lonhost"; - } - &logthis($msg); + &logthis("Result of password change for " + ."$uname: pwchange_success"); &Reply($client, "ok\n", $userinput); } else { &logthis("Unable to open $uname passwd " @@ -1837,10 +1855,7 @@ sub change_password_handler { } } else { - if ($failure eq '') { - $failure = 'non_authorized'; - } - &Failure( $client, "$failure\n", $userinput); + &Failure( $client, "non_authorized\n", $userinput); } return 1; @@ -4320,12 +4335,12 @@ sub dump_domainroles_handler { my ($start,$end) = split(/:/,&unescape($value)); my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,&unescape($key)); unless ($startfilter eq '.' || !defined($startfilter)) { - if ((defined($start)) && ($start >= $startfilter)) { + if ($start >= $startfilter) { $match = 0; } } unless ($endfilter eq '.' || !defined($endfilter)) { - if ((defined($end)) && ($end <= $endfilter)) { + if ($end <= $endfilter) { $match = 0; } } @@ -5987,7 +6002,7 @@ sub make_new_child { if ($clientip eq '127.0.0.1') { $outsideip=&Apache::lonnet::get_host_ip($perlvar{'lonHostID'}); } - + &ReadManagerTable(); my $clientrec=defined(&Apache::lonnet::get_hosts_from_ip($outsideip)); my $ismanager=($managers{$outsideip} ne undef); $clientname = "[unknonwn]";