--- loncom/lond 2001/12/22 21:46:02 1.62
+++ loncom/lond 2002/02/19 21:52:54 1.72
@@ -2,7 +2,7 @@
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
#
-# $Id: lond,v 1.62 2001/12/22 21:46:02 www Exp $
+# $Id: lond,v 1.72 2002/02/19 21:52:54 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -46,7 +46,11 @@
# 11/26,11/27 Gerd Kortemeyer
# 12/20 Scott Harrison
# 12/22 Gerd Kortemeyer
-#
+# YEAR=2002
+# 01/20/02,02/05 Gerd Kortemeyer
+# 02/05 Guy Albertelli
+# 02/07 Scott Harrison
+# 02/12 Gerd Kortemeyer
###
# based on "Perl Cookbook" ISBN 1-56592-243-3
@@ -84,6 +88,10 @@ sub catchexception {
die($error);
}
+sub timeout {
+ &logthis("CRITICAL: TIME OUT ".$$."");
+ &catchexception('Timeout');
+}
# -------------------------------- Set signal handlers to record abnormal exits
$SIG{'QUIT'}=\&catchexception;
@@ -131,7 +139,7 @@ open (CONFIG,"$perlvar{'lonTabDir'}/host
while ($configline=) {
my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
- chomp($ip);
+ chomp($ip); $ip=~s/\D+$//;
$hostid{$ip}=$id;
if ($id eq $perlvar{'lonHostID'}) { $thisserver=$name; }
$PREFORK++;
@@ -158,9 +166,13 @@ $children = 0; # cu
sub REAPER { # takes care of dead children
$SIG{CHLD} = \&REAPER;
my $pid = wait;
- $children --;
- &logthis("Child $pid died");
- delete $children{$pid};
+ if (defined($children{$pid})) {
+ &logthis("Child $pid died");
+ $children --;
+ delete $children{$pid};
+ } else {
+ &logthis("Unknown Child $pid died");
+ }
}
sub HUNTSMAN { # signal handler for SIGINT
@@ -187,6 +199,7 @@ sub checkchildren {
&initnewstatus();
&logstatus();
&logthis('Going to check on the children');
+ $docdir=$perlvar{'lonDocRoot'};
foreach (sort keys %children) {
sleep 1;
unless (kill 'USR1' => $_) {
@@ -194,6 +207,18 @@ sub checkchildren {
&logstatus($$.' is dead');
}
}
+ sleep 5;
+ foreach (sort keys %children) {
+ unless (-e "$docdir/lon-status/londchld/$_.txt") {
+ &logthis('Child '.$_.' did not respond');
+ kill 9 => $_;
+ $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
+ $subj="LON: $perlvar{'lonHostID'} killed lond process $_";
+ my $result=`echo 'Killed lond process $_.' | mailto $emailto -s '$subj' > /dev/null`;
+ $execdir=$perlvar{'lonDaemons'};
+ $result=`/bin/cp $execdir/logs/lond.log $execdir/logs/lond.log.$_`
+ }
+ }
}
# --------------------------------------------------------------------- Logging
@@ -212,8 +237,16 @@ sub logthis {
sub logstatus {
my $docdir=$perlvar{'lonDocRoot'};
+ {
my $fh=IO::File->new(">>$docdir/lon-status/londstatus.txt");
print $fh $$."\t".$status."\t".$lastlog."\n";
+ $fh->close();
+ }
+ {
+ my $fh=IO::File->new(">$docdir/lon-status/londchld/$$.txt");
+ print $fh $status."\n".$lastlog."\n".time;
+ $fh->close();
+ }
}
sub initnewstatus {
@@ -222,6 +255,11 @@ sub initnewstatus {
my $now=time;
my $local=localtime($now);
print $fh "LOND status $local - parent $$\n\n";
+ opendir(DIR,"$docdir/lon-status/londchld");
+ while ($filename=readdir(DIR)) {
+ unlink("$docdir/lon-status/londchld/$filename");
+ }
+ closedir(DIR);
}
# -------------------------------------------------------------- Status setting
@@ -431,6 +469,7 @@ sub make_new_child {
# Child can *not* return from this subroutine.
$SIG{INT} = 'DEFAULT'; # make SIGINT kill us as it did before
$SIG{USR1}= \&logstatus;
+ $SIG{ALRM}= \&timeout;
$lastlog='Forked ';
$status='Forked';
@@ -499,6 +538,7 @@ sub make_new_child {
chomp($userinput);
&status('Processing '.$hostid{$clientip}.': '.$userinput);
my $wasenc=0;
+ alarm(120);
# ------------------------------------------------------------ See if encrypted
if ($userinput =~ /^enc/) {
if ($cipher) {
@@ -600,10 +640,13 @@ sub make_new_child {
$pwdcorrect=!$?;
}
} elsif ($howpwd eq 'krb4') {
+ $null=pack("C",0);
+ unless ($upass=~/$null/) {
$pwdcorrect=(
Authen::Krb4::get_pw_in_tkt($uname,"",
$contentpwd,'krbtgt',$contentpwd,1,
$upass) == 0);
+ } else { $pwdcorrect=0; }
} elsif ($howpwd eq 'localauth') {
$pwdcorrect=&localauth::localauth($uname,$upass,
$contentpwd);
@@ -627,7 +670,8 @@ sub make_new_child {
chomp($npass);
$upass=&unescape($upass);
$npass=&unescape($npass);
- my $proname=propath($udom,$uname);
+ &logthis("Trying to change password for $uname");
+ my $proname=propath($udom,$uname);
my $passfilename="$proname/passwd";
if (-e $passfilename) {
my $realpasswd;
@@ -642,11 +686,42 @@ sub make_new_child {
my $ncpass=crypt($npass,$salt);
{ my $pf = IO::File->new(">$passfilename");
print $pf "internal:$ncpass\n"; }
+ &logthis("Result of password change for $uname: pwchange_success");
print $client "ok\n";
} else {
print $client "non_authorized\n";
}
- } else {
+ } elsif ($howpwd eq 'unix') {
+ # Unix means we have to access /etc/password
+ # one way or another.
+ # First: Make sure the current password is
+ # correct
+ $contentpwd=(getpwnam($uname))[1];
+ my $pwdcorrect = "0";
+ my $pwauth_path="/usr/local/sbin/pwauth";
+ unless ($contentpwd eq 'x') {
+ $pwdcorrect=
+ (crypt($upass,$contentpwd) eq $contentpwd);
+ } elsif (-e $pwauth_path) {
+ open PWAUTH, "|$pwauth_path" or
+ die "Cannot invoke authentication";
+ print PWAUTH "$uname\n$upass\n";
+ close PWAUTH;
+ $pwdcorrect=!$?;
+ }
+ if ($pwdcorrect) {
+ my $execdir=$perlvar{'lonDaemons'};
+ my $pf = IO::File->new("|$execdir/lcpasswd");
+ print $pf "$uname\n$npass\n$npass\n";
+ close $pf;
+ my $result = ($?>0 ? 'pwchange_failure'
+ : 'ok');
+ &logthis("Result of password change for $uname: $result");
+ print $client "$result\n";
+ } else {
+ print $client "non_authorized\n";
+ }
+ } else {
print $client "auth_mode_error\n";
}
} else {
@@ -677,7 +752,7 @@ sub make_new_child {
$fpnow.='/'.$fpparts[$i];
unless (-e $fpnow) {
unless (mkdir($fpnow,0777)) {
- $fperror="error:$!\n";
+ $fperror="error:$!";
}
}
}
@@ -1335,6 +1410,7 @@ sub make_new_child {
print $client "unknown_cmd\n";
}
# -------------------------------------------------------------------- complete
+ alarm(0);
&status('Listening to '.$hostid{$clientip});
}
# --------------------------------------------- client unknown or fishy, refuse