--- loncom/lond 2008/05/30 21:34:27 1.394.2.1 +++ loncom/lond 2009/04/11 14:47:46 1.413 @@ -2,7 +2,7 @@ # The LearningOnline Network # lond "LON Daemon" Server (port "LOND" 5663) # -# $Id: lond,v 1.394.2.1 2008/05/30 21:34:27 raeburn Exp $ +# $Id: lond,v 1.413 2009/04/11 14:47:46 raeburn 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.394.2.1 $'; #' stupid emacs +my $VERSION='$Revision: 1.413 $'; #' 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,14 +1240,17 @@ sub push_file_handler { &Reply($client, \$reply, $userinput); } else { + &logthis("push_file_handler $client is not valid"); &Failure( $client, "refused\n", $userinput); } return 1; } ®ister_handler("pushfile", \&push_file_handler, 1, 0, 1); +# The du_handler routine should be considered obsolete and is retained +# for communication with legacy servers. Please see the du2_handler. # -# du - list the disk usuage of a directory recursively. +# du - list the disk usage of a directory recursively. # # note: stolen code from the ls file handler # under construction by Rick Banghart @@ -1272,9 +1300,73 @@ sub du_handler { } ®ister_handler("du", \&du_handler, 0, 1, 0); +# Please also see the du_handler, which is obsoleted by du2. +# du2_handler differs from du_handler in that required path to directory +# provided by &propath() is prepended in the handler instead of on the +# client side. # -# The ls_handler routine should be considered obosolete and is retained -# for communication with legacy servers. Please see the ls2_handler. +# du2 - list the disk usage of a directory recursively. +# +# Parameters: +# $cmd - The command that dispatched us (du). +# $tail - The tail of the request that invoked us. +# $tail is a : separated list of the following: +# - $ududir - directory path to list (before prepending) +# - $getpropath = 1 if &propath() should prepend +# - $uname - username to use for &propath or user dir +# - $udom - domain to use for &propath or user dir +# All are escaped. +# $client - Socket open on the client. +# Returns: +# 1 - indicating that the daemon should not disconnect. +# Side Effects: +# The reply is written to $client. +# + +sub du2_handler { + my ($cmd, $tail, $client) = @_; + my ($ududir,$getpropath,$uname,$udom) = map { &unescape($_) } (split(/:/, $tail)); + my $userinput = "$cmd:$tail"; + if (($ududir=~/\.\./) || (($ududir!~m|^/home/httpd/|) && (!$getpropath))) { + &Failure($client,"refused\n","$cmd:$tail"); + return 1; + } + if ($getpropath) { + if (($uname =~ /^$LONCAPA::match_name$/) && ($udom =~ /^$LONCAPA::match_domain$/)) { + $ududir = &propath($udom,$uname).'/'.$ududir; + } else { + &Failure($client,"refused\n","$cmd:$tail"); + return 1; + } + } + # Since $ududir could have some nasties in it, + # we will require that ududir is a valid + # directory. Just in case someone tries to + # slip us a line like .;(cd /home/httpd rm -rf*) + # etc. + # + if (-d $ududir) { + my $total_size=0; + my $code=sub { + if ($_=~/\.\d+\./) { return;} + if ($_=~/\.meta$/) { return;} + if (-d $_) { return;} + $total_size+=(stat($_))[7]; + }; + chdir($ududir); + find($code,$ududir); + $total_size=int($total_size/1024); + &Reply($client,\$total_size,"$cmd:$ududir"); + } else { + &Failure($client, "bad_directory:$ududir\n","$cmd:$tail"); + } + return 1; +} +®ister_handler("du2", \&du2_handler, 0, 1, 0); + +# +# The ls_handler routine should be considered obsolete and is retained +# for communication with legacy servers. Please see the ls3_handler. # # ls - list the contents of a directory. For each file in the # selected directory the filename followed by the full output of @@ -1340,8 +1432,9 @@ sub ls_handler { } ®ister_handler("ls", \&ls_handler, 0, 1, 0); -# -# Please also see the ls_handler, which this routine obosolets. +# The ls2_handler routine should be considered obsolete and is retained +# for communication with legacy servers. Please see the ls3_handler. +# Please also see the ls_handler, which was itself obsoleted by ls2. # ls2_handler differs from ls_handler in that it escapes its return # values before concatenating them together with ':'s. # @@ -1406,6 +1499,159 @@ sub ls2_handler { return 1; } ®ister_handler("ls2", \&ls2_handler, 0, 1, 0); +# +# ls3 - list the contents of a directory. For each file in the +# selected directory the filename followed by the full output of +# the stat function is returned. The returned info for each +# file are separated by ':'. The stat fields are separated by &'s. +# Parameters: +# $cmd - The command that dispatched us (ls). +# $tail - The tail of the request that invoked us. +# $tail is a : separated list of the following: +# - $ulsdir - directory path to list (before prepending) +# - $getpropath = 1 if &propath() should prepend +# - $getuserdir = 1 if path to user dir in lonUsers should +# prepend +# - $alternate_root - path to prepend +# - $uname - username to use for &propath or user dir +# - $udom - domain to use for &propath or user dir +# All of these except $getpropath and &getuserdir are escaped. +# no_such_dir. +# $client - Socket open on the client. +# Returns: +# 1 - indicating that the daemon should not disconnect. +# Side Effects: +# The reply is written to $client. +# + +sub ls3_handler { + my ($cmd, $tail, $client) = @_; + my $userinput = "$cmd:$tail"; + my ($ulsdir,$getpropath,$getuserdir,$alternate_root,$uname,$udom) = + split(/:/,$tail); + if (defined($ulsdir)) { + $ulsdir = &unescape($ulsdir); + } + if (defined($alternate_root)) { + $alternate_root = &unescape($alternate_root); + } + if (defined($uname)) { + $uname = &unescape($uname); + } + if (defined($udom)) { + $udom = &unescape($udom); + } + + my $dir_root = $perlvar{'lonDocRoot'}; + if ($getpropath) { + if (($uname =~ /^$LONCAPA::match_name$/) && ($udom =~ /^$LONCAPA::match_domain$/)) { + $dir_root = &propath($udom,$uname); + $dir_root =~ s/\/$//; + } else { + &Failure($client,"refused\n","$cmd:$tail"); + return 1; + } + } elsif ($getuserdir) { + if (($uname =~ /^$LONCAPA::match_name$/) && ($udom =~ /^$LONCAPA::match_domain$/)) { + my $subdir=$uname.'__'; + $subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/; + $dir_root = $Apache::lonnet::perlvar{'lonUsersDir'} + ."/$udom/$subdir/$uname"; + } else { + &Failure($client,"refused\n","$cmd:$tail"); + return 1; + } + } elsif ($alternate_root ne '') { + $dir_root = $alternate_root; + } + if (($dir_root ne '') && ($dir_root ne '/')) { + if ($ulsdir =~ /^\//) { + $ulsdir = $dir_root.$ulsdir; + } else { + $ulsdir = $dir_root.'/'.$ulsdir; + } + } + my $obs; + my $rights; + my $ulsout=''; + my $ulsfn; + if (-e $ulsdir) { + if(-d $ulsdir) { + if (opendir(LSDIR,$ulsdir)) { + while ($ulsfn=readdir(LSDIR)) { + undef($obs); + undef($rights); + my @ulsstats=stat($ulsdir.'/'.$ulsfn); + #We do some obsolete checking here + if(-e $ulsdir.'/'.$ulsfn.".meta") { + open(FILE, $ulsdir.'/'.$ulsfn.".meta"); + my @obsolete=; + foreach my $obsolete (@obsolete) { + if($obsolete =~ m/()(on|1)/) { $obs = 1; } + if($obsolete =~ m|()(default)|) { + $rights = 1; + } + } + } + my $tmp = $ulsfn.'&'.join('&',@ulsstats); + if ($obs eq '1') { $tmp.="&1"; } else { $tmp.="&0"; } + if ($rights eq '1') { $tmp.="&1"; } else { $tmp.="&0"; } + $ulsout.= &escape($tmp).':'; + } + closedir(LSDIR); + } + } else { + my @ulsstats=stat($ulsdir); + $ulsout.=$ulsfn.'&'.join('&',@ulsstats).':'; + } + } else { + $ulsout='no_such_dir'; + } + if ($ulsout eq '') { $ulsout='empty'; } + &Reply($client, \$ulsout, $userinput); # This supports debug logging. + return 1; +} +®ister_handler("ls3", \&ls3_handler, 0, 1, 0); + +sub server_timezone_handler { + my ($cmd,$tail,$client) = @_; + my $userinput = "$cmd:$tail"; + my $timezone; + my $clockfile = '/etc/sysconfig/clock'; # Fedora/CentOS/SuSE + my $tzfile = '/etc/timezone'; # Debian/Ubuntu + if (-e $clockfile) { + if (open(my $fh,"<$clockfile")) { + while (<$fh>) { + next if (/^[\#\s]/); + if (/^(?:TIME)?ZONE\s*=\s*['"]?\s*([\w\/]+)/) { + $timezone = $1; + last; + } + } + close($fh); + } + } elsif (-e $tzfile) { + if (open(my $fh,"<$tzfile")) { + $timezone = <$fh>; + close($fh); + chomp($timezone); + if ($timezone =~ m{^Etc/(\w+)$}) { + $timezone = $1; + } + } + } + &Reply($client,\$timezone,$userinput); # This supports debug logging. + return 1; +} +®ister_handler("servertimezone", \&server_timezone_handler, 0, 1, 0); + +sub server_loncaparev_handler { + my ($cmd,$tail,$client) = @_; + my $userinput = "$cmd:$tail"; + &Reply($client,\$perlvar{'lonVersion'},$userinput); + return 1; +} +®ister_handler("serverloncaparev", \&server_loncaparev_handler, 0, 1, 0); # Process a reinit request. Reinit requests that either # lonc or lond be reinitialized so that an updated @@ -1514,13 +1760,15 @@ sub authenticate_handler { # udom - User's domain. # uname - Username. # upass - User's password. + # checkdefauth - Pass to validate_user() to try authentication + # with default auth type(s) if no user account. - my ($udom,$uname,$upass)=split(/:/,$tail); - &Debug(" Authenticate domain = $udom, user = $uname, password = $upass"); + my ($udom, $uname, $upass, $checkdefauth)=split(/:/,$tail); + &Debug(" Authenticate domain = $udom, user = $uname, password = $upass, checkdefauth = $checkdefauth"); chomp($upass); $upass=&unescape($upass); - my $pwdcorrect = &validate_user($udom, $uname, $upass); + my $pwdcorrect = &validate_user($udom,$uname,$upass,$checkdefauth); if($pwdcorrect) { &Reply( $client, "authorized\n", $userinput); # @@ -3433,7 +3681,17 @@ sub put_course_id_hash_handler { # key, value pairs in the item's hash, or as a # colon-separated list of (in order) description, # institutional code, and course owner. -# +# selfenrollonly - filter by courses allowing self-enrollment +# now or in the future (selfenrollonly = 1). +# catfilter - filter by course category, assigned to a course +# using manually defined categories (i.e., not +# self-cataloging based on on institutional code). +# showhidden - include course in results even if course +# was set to be excluded from course catalog (DC only). +# caller - if set to 'coursecatalog', courses set to be hidden +# from course catalog will be excluded from results (unless +# overridden by "showhidden". +# # $client - The socket open on the client. # Returns: # 1 - Continue processing. @@ -3444,7 +3702,9 @@ sub dump_course_id_handler { my $userinput = "$cmd:$tail"; my ($udom,$since,$description,$instcodefilter,$ownerfilter,$coursefilter, - $typefilter,$regexp_ok,$rtn_as_hash) =split(/:/,$tail); + $typefilter,$regexp_ok,$rtn_as_hash,$selfenrollonly,$catfilter,$showhidden, + $caller) =split(/:/,$tail); + my $now = time; if (defined($description)) { $description=&unescape($description); } else { @@ -3484,6 +3744,9 @@ sub dump_course_id_handler { if (defined($regexp_ok)) { $regexp_ok=&unescape($regexp_ok); } + if (defined($catfilter)) { + $catfilter=&unescape($catfilter); + } my $unpack = 1; if ($description eq '.' && $instcodefilter eq '.' && $coursefilter eq '.' && $typefilter eq '.') { @@ -3494,7 +3757,8 @@ sub dump_course_id_handler { my $hashref = &tie_domain_hash($udom, "nohist_courseids", &GDBM_WRCREAT()); if ($hashref) { while (my ($key,$value) = each(%$hashref)) { - my ($unesc_key,$lasttime_key,$lasttime,$is_hash,%val,%unesc_val); + my ($unesc_key,$lasttime_key,$lasttime,$is_hash,%val, + %unesc_val,$selfenroll_end,$selfenroll_types); $unesc_key = &unescape($key); if ($unesc_key =~ /^lasttime:/) { next; @@ -3514,7 +3778,36 @@ sub dump_course_id_handler { $unesc_val{'owner'} = $items->{'owner'}; $unesc_val{'type'} = $items->{'type'}; } + $selfenroll_types = $items->{'selfenroll_types'}; + $selfenroll_end = $items->{'selfenroll_end_date'}; + if ($selfenrollonly) { + next if (!$selfenroll_types); + if (($selfenroll_end > 0) && ($selfenroll_end <= $now)) { + next; + } + } + if ($catfilter ne '') { + next if ($items->{'categories'} eq ''); + my @categories = split('&',$items->{'categories'}); + next if (@categories == 0); + my @subcats = split('&',$catfilter); + my $matchcat = 0; + foreach my $cat (@categories) { + if (grep(/^\Q$cat\E$/,@subcats)) { + $matchcat = 1; + last; + } + } + next if (!$matchcat); + } + if ($caller eq 'coursecatalog') { + if ($items->{'hidefromcat'} eq 'yes') { + next if !$showhidden; + } + } } else { + next if ($catfilter ne ''); + next if ($selfenrollonly); $is_hash = 0; my @courseitems = split(/:/,$value); $lasttime = pop(@courseitems); @@ -4703,6 +4996,40 @@ sub get_institutional_id_rules { } ®ister_handler("instidrules",\&get_institutional_id_rules,0,1,0); +sub get_institutional_selfcreate_rules { + my ($cmd, $tail, $client) = @_; + my $userinput = "$cmd:$tail"; + my $dom = &unescape($tail); + my (%rules_hash,@rules_order); + my $outcome; + eval { + local($SIG{__DIE__})='DEFAULT'; + $outcome = &localenroll::selfcreate_rules($dom,\%rules_hash,\@rules_order); + }; + if (!$@) { + if ($outcome eq 'ok') { + my $result; + foreach my $key (keys(%rules_hash)) { + $result .= &escape($key).'='.&Apache::lonnet::freeze_escape($rules_hash{$key}).'&'; + } + $result =~ s/\&$//; + $result .= ':'; + if (@rules_order > 0) { + foreach my $item (@rules_order) { + $result .= &escape($item).'&'; + } + } + $result =~ s/\&$//; + &Reply($client,\$result,$userinput); + } else { + &Reply($client,"error\n", $userinput); + } + } else { + &Failure($client,"unknown_cmd\n",$userinput); + } +} +®ister_handler("instemailrules",\&get_institutional_selfcreate_rules,0,1,0); + sub institutional_username_check { my ($cmd, $tail, $client) = @_; @@ -4762,6 +5089,35 @@ sub institutional_id_check { } ®ister_handler("instidrulecheck",\&institutional_id_check,0,1,0); +sub institutional_selfcreate_check { + my ($cmd, $tail, $client) = @_; + my $userinput = "$cmd:$tail"; + my %rulecheck; + my $outcome; + my ($udom,$email,@rules) = split(/:/,$tail); + $udom = &unescape($udom); + $email = &unescape($email); + @rules = map {&unescape($_);} (@rules); + eval { + local($SIG{__DIE__})='DEFAULT'; + $outcome = &localenroll::selfcreate_check($udom,$email,\@rules,\%rulecheck); + }; + if (!$@) { + if ($outcome eq 'ok') { + my $result=''; + foreach my $key (keys(%rulecheck)) { + $result.=&escape($key).'='.&Apache::lonnet::freeze_escape($rulecheck{$key}).'&'; + } + &Reply($client,\$result,$userinput); + } else { + &Reply($client,"error\n", $userinput); + } + } else { + &Failure($client,"unknown_cmd\n",$userinput); + } +} +®ister_handler("instselfcreatecheck",\&institutional_selfcreate_check,0,1,0); + # Get domain specific conditions for import of student photographs to a course # # Retrieves information from photo_permission subroutine in localenroll. @@ -5654,7 +6010,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]"; @@ -5972,8 +6328,7 @@ sub get_auth_type # 0 - The domain,user,password triplet is not a valid user. # sub validate_user { - my ($domain, $user, $password) = @_; - + my ($domain, $user, $password, $checkdefauth) = @_; # Why negative ~pi you may well ask? Well this function is about # authentication, and therefore very important to get right. @@ -5996,8 +6351,21 @@ sub validate_user { my $null = pack("C",0); # Used by kerberos auth types. + if ($howpwd eq 'nouser') { + if ($checkdefauth) { + my %domdefaults = &Apache::lonnet::get_domain_defaults($domain); + if ($domdefaults{'auth_def'} eq 'localauth') { + $howpwd = $domdefaults{'auth_def'}; + $contentpwd = $domdefaults{'auth_arg_def'}; + } elsif ((($domdefaults{'auth_def'} eq 'krb4') || + ($domdefaults{'auth_def'} eq 'krb5')) && + ($domdefaults{'auth_arg_def'} ne '')) { + $howpwd = $domdefaults{'auth_def'}; + $contentpwd = $domdefaults{'auth_arg_def'}; + } + } + } if ($howpwd ne 'nouser') { - if($howpwd eq "internal") { # Encrypted is in local password file. $validated = (crypt($password, $contentpwd) eq $contentpwd); } @@ -6816,3 +7184,406 @@ linux Server/Process =cut + + +=pod + +=head1 LOG MESSAGES + +The messages below can be emitted in the lond log. This log is located +in ~httpd/perl/logs/lond.log Many log messages have HTML encapsulation +to provide coloring if examined from inside a web page. Some do not. +Where color is used, the colors are; Red for sometihhng to get excited +about and to follow up on. Yellow for something to keep an eye on to +be sure it does not get worse, Green,and Blue for informational items. + +In the discussions below, sometimes reference is made to ~httpd +when describing file locations. There isn't really an httpd +user, however there is an httpd directory that gets installed in the +place that user home directories go. On linux, this is usually +(always?) /home/httpd. + + +Some messages are colorless. These are usually (not always) +Green/Blue color level messages. + +=over 2 + +=item (Red) LocalConnection rejecting non local: ne 127.0.0.1 + +A local connection negotiation was attempted by +a host whose IP address was not 127.0.0.1. +The socket is closed and the child will exit. +lond has three ways to establish an encyrption +key with a client: + +=over 2 + +=item local + +The key is written and read from a file. +This is only valid for connections from localhost. + +=item insecure + +The key is generated by the server and +transmitted to the client. + +=item ssl (secure) + +An ssl connection is negotiated with the client, +the key is generated by the server and sent to the +client across this ssl connection before the +ssl connectionis terminated and clear text +transmission resumes. + +=back + +=item (Red) LocalConnection: caller is insane! init = and type = + +The client is local but has not sent an initialization +string that is the literal "init:local" The connection +is closed and the child exits. + +=item Red CRITICAL Can't get key file + +SSL key negotiation is being attempted but the call to +lonssl::KeyFile failed. This usually means that the +configuration file is not correctly defining or protecting +the directories/files lonCertificateDirectory or +lonnetPrivateKey + is a string that describes the reason that +the key file could not be located. + +=item (Red) CRITICAL Can't get certificates + +SSL key negotiation failed because we were not able to retrives our certificate +or the CA's certificate in the call to lonssl::CertificateFile + is the textual reason this failed. Usual reasons: + +=over 2 + +=item Apache config file for loncapa incorrect: + +one of the variables +lonCertificateDirectory, lonnetCertificateAuthority, or lonnetCertificate +undefined or incorrect + +=item Permission error: + +The directory pointed to by lonCertificateDirectory is not readable by lond + +=item Permission error: + +Files in the directory pointed to by lonCertificateDirectory are not readable by lond. + +=item Installation error: + +Either the certificate authority file or the certificate have not +been installed in lonCertificateDirectory. + +=item (Red) CRITICAL SSL Socket promotion failed: + +The promotion of the connection from plaintext to SSL failed + is the reason for the failure. There are two +system calls involved in the promotion (one of which failed), +a dup to produce +a second fd on the raw socket over which the encrypted data +will flow and IO::SOcket::SSL->new_from_fd which creates +the SSL connection on the duped fd. + +=item (Blue) WARNING client did not respond to challenge + +This occurs on an insecure (non SSL) connection negotiation request. +lond generates some number from the time, the PID and sends it to +the client. The client must respond by echoing this information back. +If the client does not do so, that's a violation of the challenge +protocols and the connection will be failed. + +=item (Red) No manager table. Nobody can manage!! + +lond has the concept of privileged hosts that +can perform remote management function such +as update the hosts.tab. The manager hosts +are described in the +~httpd/lonTabs/managers.tab file. +this message is logged if this file is missing. + + +=item (Green) Registering manager as with + +Reports the successful parse and registration +of a specific manager. + +=item Green existing host + +The manager host is already defined in the hosts.tab +the information in that table, rather than the info in the +manager table will be used to determine the manager's ip. + +=item (Red) Unable to craete + +lond has been asked to create new versions of an administrative +file (by a manager). When this is done, the new file is created +in a temp file and then renamed into place so that there are always +usable administrative files, even if the update fails. This failure +message means that the temp file could not be created. +The update is abandoned, and the old file is available for use. + +=item (Green) CopyFile from to failed + +In an update of administrative files, the copy of the existing file to a +backup file failed. The installation of the new file may still succeed, +but there will not be a back up file to rever to (this should probably +be yellow). + +=item (Green) Pushfile: backed up to + +See above, the backup of the old administrative file succeeded. + +=item (Red) Pushfile: Unable to install + +The new administrative file could not be installed. In this case, +the old administrative file is still in use. + +=item (Green) Installed new < filename>. + +The new administrative file was successfullly installed. + +=item (Red) Reinitializing lond pid= + +The lonc child process will be sent a USR2 +signal. + +=item (Red) Reinitializing self + +We've been asked to re-read our administrative files,and +are doing so. + +=item (Yellow) error:Invalid process identifier + +A reinit command was received, but the target part of the +command was not valid. It must be either +'lond' or 'lonc' but was + +=item (Green) isValideditCommand checking: Command = Key = newline = + +Checking to see if lond has been handed a valid edit +command. It is possible the edit command is not valid +in that case there are no log messages to indicate that. + +=item Result of password change for pwchange_success + +The password for was +successfully changed. + +=item Unable to open passwd to change password + +Could not rewrite the +internal password file for a user + +=item Result of password change for : + +A unix password change for was attempted +and the pipe returned + +=item LWP GET: for () + +The lightweight process fetch for a resource failed +with the local filename that should +have existed/been created was the +corresponding URI: This is emitted in several +places. + +=item Unable to move to + +From fetch_user_file_handler - the user file was replicated but could not +be mv'd to its final location. + +=item Looking for + +From user_has_session_handler - This should be a Debug call instead +it indicates lond is about to check whether the specified user has a +session active on the specified domain on the local host. + +=item Client () hanging up: + +lond has been asked to exit by its client. The and identify the +client systemand is the full exit command sent to the server. + +=item Red CRITICAL: ABNORMAL EXIT. child for server died through a crass with this error->[]. + +A lond child terminated. NOte that this termination can also occur when the +child receives the QUIT or DIE signals. is the process id of the child, + the host lond is working for, and the reason the child died +to the best of our ability to get it (I would guess that any numeric value +represents and errno value). This is immediately followed by + +=item Famous last words: Catching exception - + +Where log is some recent information about the state of the child. + +=item Red CRITICAL: TIME OUT + +Some timeout occured for server . THis is normally a timeout on an LWP +doing an HTTP::GET. + +=item child died + +The reaper caught a SIGCHILD for the lond child process +This should be modified to also display the IP of the dying child +$children{$pid} + +=item Unknown child 0 died +A child died but the wait for it returned a pid of zero which really should not +ever happen. + +=item Child - looks like we missed it's death + +When a sigchild is received, the reaper process checks all children to see if they are +alive. If children are dying quite quickly, the lack of signal queuing can mean +that a signal hearalds the death of more than one child. If so this message indicates +which other one died. is the ip of a dead child + +=item Free socket: + +The HUNTSMAN sub was called due to a SIGINT in a child process. The socket is being shutdown. +for whatever reason, is printed but in fact shutdown() is not documented +to return anything. This is followed by: + +=item Red CRITICAL: Shutting down + +Just prior to exit. + +=item Free socket: + +The HUPSMAN sub was called due to a SIGHUP. all children get killsed, and lond execs itself. +This is followed by: + +=item (Red) CRITICAL: Restarting + +lond is about to exec itself to restart. + +=item (Blue) Updating connections + +(In response to a USR2). All the children (except the one for localhost) +are about to be killed, the hosts tab reread, and Apache reloaded via apachereload. + +=item (Blue) UpdateHosts killing child for ip + +Due to USR2 as above. + +=item (Green) keeping child for ip (pid = ) + +In response to USR2 as above, the child indicated is not being restarted because +it's assumed that we'll always need a child for the localhost. + + +=item Going to check on the children + +Parent is about to check on the health of the child processes. +Note that this is in response to a USR1 sent to the parent lond. +there may be one or more of the next two messages: + +=item is dead + +A child that we have in our child hash as alive has evidently died. + +=item Child did not respond + +In the health check the child did not update/produce a pid_.txt +file when sent it's USR1 signal. That process is killed with a 9 signal, as it's +assumed to be hung in some un-fixable way. + +=item Finished checking children + +Master processs's USR1 processing is cojmplete. + +=item (Red) CRITICAL: ------- Starting ------ + +(There are more '-'s on either side). Lond has forked itself off to +form a new session and is about to start actual initialization. + +=item (Green) Attempting to start child () + +Started a new child process for . Client is IO::Socket object +connected to the child. This was as a result of a TCP/IP connection from a client. + +=item Unable to determine who caller was, getpeername returned nothing + +In child process initialization. either getpeername returned undef or +a zero sized object was returned. Processing continues, but in my opinion, +this should be cause for the child to exit. + +=item Unable to determine clientip + +In child process initialization. The peer address from getpeername was not defined. +The client address is stored as "Unavailable" and processing continues. + +=item (Yellow) INFO: Connection connection type = + +In child initialization. A good connectionw as received from . + +=over 2 + +=item + +is the name of the client from hosts.tab. + +=item + +Is the connection type which is either + +=over 2 + +=item manager + +The connection is from a manager node, not in hosts.tab + +=item client + +the connection is from a non-manager in the hosts.tab + +=item both + +The connection is from a manager in the hosts.tab. + +=back + +=back + +=item (Blue) Certificates not installed -- trying insecure auth + +One of the certificate file, key file or +certificate authority file could not be found for a client attempting +SSL connection intiation. COnnection will be attemptied in in-secure mode. +(this would be a system with an up to date lond that has not gotten a +certificate from us). + +=item (Green) Successful local authentication + +A local connection successfully negotiated the encryption key. +In this case the IDEA key is in a file (that is hopefully well protected). + +=item (Green) Successful ssl authentication with + +The client ( is the peer's name in hosts.tab), has successfully +negotiated an SSL connection with this child process. + +=item (Green) Successful insecure authentication with + + +The client has successfully negotiated an insecure connection withthe child process. + +=item (Yellow) Attempted insecure connection disallowed + +The client attempted and failed to successfully negotiate a successful insecure +connection. This can happen either because the variable londAllowInsecure is false +or undefined, or becuse the child did not successfully echo back the challenge +string. + + +=back + + +=cut 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.