version 1.489.2.35.2.1, 2020/01/13 14:05:54
|
version 1.489.2.43, 2021/12/21 16:22:14
|
Line 1795 sub read_lonnet_global {
|
Line 1795 sub read_lonnet_global {
|
} |
} |
if ($what eq 'perlvar') { |
if ($what eq 'perlvar') { |
if (!exists($packagevars{$what}{'lonBalancer'})) { |
if (!exists($packagevars{$what}{'lonBalancer'})) { |
if ($dist =~ /^(centos|rhes|fedora|scientific|oracle)/) { |
if ($dist =~ /^(centos|rhes|fedora|scientific|oracle|rocky|alma)/) { |
my $othervarref=LONCAPA::Configuration::read_conf('httpd.conf'); |
my $othervarref=LONCAPA::Configuration::read_conf('httpd.conf'); |
if (ref($othervarref) eq 'HASH') { |
if (ref($othervarref) eq 'HASH') { |
$items->{'lonBalancer'} = $othervarref->{'lonBalancer'}; |
$items->{'lonBalancer'} = $othervarref->{'lonBalancer'}; |
Line 4576 sub course_lastaccess_handler {
|
Line 4576 sub course_lastaccess_handler {
|
} |
} |
®ister_handler("courselastaccess",\&course_lastaccess_handler, 0, 1, 0); |
®ister_handler("courselastaccess",\&course_lastaccess_handler, 0, 1, 0); |
|
|
|
sub course_sessions_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
my $userinput = "$cmd:$tail"; |
|
my ($cdom,$cnum,$lastactivity) = split(':',$tail); |
|
my $dbsuffix = '_'.$cdom.'_'.$cnum.'.db'; |
|
my (%sessions,$qresult); |
|
my $now=time; |
|
if (opendir(DIR,$perlvar{'lonIDsDir'})) { |
|
my $filename; |
|
while ($filename=readdir(DIR)) { |
|
next if ($filename=~/^\./); |
|
next if ($filename=~/^publicuser_/); |
|
next if ($filename=~/^[a-f0-9]+_(linked|lti_\d+)\.id$/); |
|
if ($filename =~ /^($LONCAPA::match_username)_\d+_($LONCAPA::match_domain)_/) { |
|
my ($uname,$udom) = ($1,$2); |
|
next unless (-e "$perlvar{'lonDaemons'}/tmp/$uname$dbsuffix"); |
|
my $mtime = (stat("$perlvar{'lonIDsDir'}/$filename"))[9]; |
|
if ($lastactivity < 0) { |
|
next if ($mtime-$now > $lastactivity); |
|
} else { |
|
next if ($now-$mtime > $lastactivity); |
|
} |
|
$sessions{$uname.':'.$udom} = $mtime; |
|
} |
|
} |
|
closedir(DIR); |
|
} |
|
foreach my $user (keys(%sessions)) { |
|
$qresult.=&escape($user).'='.$sessions{$user}.'&'; |
|
} |
|
if ($qresult) { |
|
chop($qresult); |
|
} |
|
&Reply($client, \$qresult, $userinput); |
|
return 1; |
|
} |
|
®ister_handler("coursesessions",\&course_sessions_handler, 0, 1, 0); |
|
|
# |
# |
# Puts an unencrypted entry in a namespace db file at the domain level |
# Puts an unencrypted entry in a namespace db file at the domain level |
# |
# |
Line 4624 sub put_domain_handler {
|
Line 4662 sub put_domain_handler {
|
# domain directory. |
# domain directory. |
# |
# |
# Parameters: |
# Parameters: |
# $cmd - Command request keyword (get). |
# $cmd - Command request keyword (getdom). |
# $tail - Tail of the command. This is a colon separated list |
# $tail - Tail of the command. This is a colon separated list |
# consisting of the domain and the 'namespace' |
# consisting of the domain and the 'namespace' |
# which selects the gdbm file to do the lookup in, |
# which selects the gdbm file to do the lookup in, |
Line 4641 sub put_domain_handler {
|
Line 4679 sub put_domain_handler {
|
sub get_domain_handler { |
sub get_domain_handler { |
my ($cmd, $tail, $client) = @_; |
my ($cmd, $tail, $client) = @_; |
|
|
|
|
my $userinput = "$cmd:$tail"; |
my $userinput = "$cmd:$tail"; |
|
|
my ($udom,$namespace,$what)=split(/:/,$tail,3); |
my ($udom,$namespace,$what)=split(/:/,$tail,3); |
chomp($what); |
my $res = LONCAPA::Lond::get_dom($userinput); |
if ($namespace =~ /^enc/) { |
if ($res =~ /^error:/) { |
&Failure( $client, "refused\n", $userinput); |
&Failure($client, \$res, $userinput); |
} else { |
} else { |
my @queries=split(/\&/,$what); |
&Reply($client, \$res, $userinput); |
my $qresult=''; |
|
my $hashref = &tie_domain_hash($udom, "$namespace", &GDBM_READER()); |
|
if ($hashref) { |
|
for (my $i=0;$i<=$#queries;$i++) { |
|
$qresult.="$hashref->{$queries[$i]}&"; |
|
} |
|
if (&untie_domain_hash($hashref)) { |
|
$qresult=~s/\&$//; |
|
&Reply($client, \$qresult, $userinput); |
|
} else { |
|
&Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". |
|
"while attempting getdom\n",$userinput); |
|
} |
|
} else { |
|
&Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". |
|
"while attempting getdom\n",$userinput); |
|
} |
|
} |
} |
|
|
return 1; |
return 1; |
} |
} |
®ister_handler("getdom", \&get_domain_handler, 0, 1, 0); |
®ister_handler("getdom", \&get_domain_handler, 0, 1, 0); |
|
|
sub encrypted_get_domain_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my ($udom,$namespace,$what)=split(/:/,$tail,3); |
|
chomp($what); |
|
my @queries=split(/\&/,$what); |
|
my $qresult=''; |
|
my $hashref = &tie_domain_hash($udom, "$namespace", &GDBM_READER()); |
|
if ($hashref) { |
|
for (my $i=0;$i<=$#queries;$i++) { |
|
$qresult.="$hashref->{$queries[$i]}&"; |
|
} |
|
if (&untie_domain_hash($hashref)) { |
|
$qresult=~s/\&$//; |
|
if ($cipher) { |
|
my $cmdlength=length($qresult); |
|
$qresult.=" "; |
|
my $encqresult=''; |
|
for (my $encidx=0;$encidx<=$cmdlength;$encidx+=8) { |
|
$encqresult.= unpack("H16", |
|
$cipher->encrypt(substr($qresult, |
|
$encidx, |
|
8))); |
|
} |
|
&Reply( $client, "enc:$cmdlength:$encqresult\n", $userinput); |
|
} else { |
|
&Failure( $client, "error:no_key\n", $userinput); |
|
} |
|
} else { |
|
&Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". |
|
"while attempting egetdom\n",$userinput); |
|
} |
|
} else { |
|
&Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". |
|
"while attempting egetdom\n",$userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("egetdom", \&encrypted_get_domain_handler, 1, 1, 0); |
|
|
|
# |
# |
# Puts an id to a domains id database. |
# Puts an id to a domains id database. |
# |
# |
Line 5140 sub tmp_put_handler {
|
Line 5118 sub tmp_put_handler {
|
} |
} |
my ($id,$store); |
my ($id,$store); |
$tmpsnum++; |
$tmpsnum++; |
if (($context eq 'resetpw') || ($context eq 'createaccount')) { |
my $numtries = 0; |
$id = &md5_hex(&md5_hex(time.{}.rand().$$)); |
my $execdir=$perlvar{'lonDaemons'}; |
|
if (($context eq 'resetpw') || ($context eq 'createaccount') || |
|
($context eq 'sso') || ($context eq 'link') || ($context eq 'retry')) { |
|
$id = &md5_hex(&md5_hex(time.{}.rand().$$.$tmpsnum)); |
|
while ((-e "$execdir/tmp/$id.tmp") && ($numtries <10)) { |
|
undef($id); |
|
$id = &md5_hex(&md5_hex(time.{}.rand().$$.$tmpsnum)); |
|
$numtries ++; |
|
} |
} else { |
} else { |
$id = $$.'_'.$clientip.'_'.$tmpsnum; |
$id = $$.'_'.$clientip.'_'.$tmpsnum; |
} |
} |
$id=~s/\W/\_/g; |
$id=~s/\W/\_/g; |
$record=~s/\n//g; |
$record=~s/\n//g; |
my $execdir=$perlvar{'lonDaemons'}; |
if (($id ne '') && |
if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) { |
($store=IO::File->new(">$execdir/tmp/$id.tmp"))) { |
print $store $record; |
print $store $record; |
close $store; |
close $store; |
&Reply($client, \$id, $userinput); |
&Reply($client, \$id, $userinput); |
Line 5231 sub tmp_del_handler {
|
Line 5217 sub tmp_del_handler {
|
®ister_handler("tmpdel", \&tmp_del_handler, 0, 1, 0); |
®ister_handler("tmpdel", \&tmp_del_handler, 0, 1, 0); |
|
|
# |
# |
|
# Process the updatebalcookie command. This command updates a |
|
# cookie in the lonBalancedir directory on a load balancer node. |
|
# |
|
# Parameters: |
|
# $cmd - Command that got us here. |
|
# $tail - Tail of the request (escaped cookie: escaped current entry) |
|
# |
|
# $client - socket open on the client process. |
|
# |
|
# Returns: |
|
# 1 - Indicating processing should continue. |
|
# Side Effects: |
|
# A cookie file is updated from the lonBalancedir directory |
|
# A reply is sent to the client. |
|
# |
|
sub update_balcookie_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput= "$cmd:$tail"; |
|
chomp($tail); |
|
my ($cookie,$lastentry) = map { &unescape($_) } (split(/:/,$tail)); |
|
|
|
my $updatedone; |
|
if ($cookie =~ /^$LONCAPA::match_domain\_$LONCAPA::match_username\_[a-f0-9]{32}$/) { |
|
my $execdir=$perlvar{'lonBalanceDir'}; |
|
if (-e "$execdir/$cookie.id") { |
|
my $doupdate; |
|
if (open(my $fh,'<',"$execdir/$cookie.id")) { |
|
while (my $line = <$fh>) { |
|
chomp($line); |
|
if ($line eq $lastentry) { |
|
$doupdate = 1; |
|
last; |
|
} |
|
} |
|
close($fh); |
|
} |
|
if ($doupdate) { |
|
if (open(my $fh,'>',"$execdir/$cookie.id")) { |
|
print $fh $clientname; |
|
close($fh); |
|
$updatedone = 1; |
|
} |
|
} |
|
} |
|
} |
|
if ($updatedone) { |
|
&Reply($client, "ok\n", $userinput); |
|
} else { |
|
&Failure( $client, "error: ".($!+0)."file update failed ". |
|
"while attempting updatebalcookie\n", $userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("updatebalcookie", \&update_balcookie_handler, 0, 1, 0); |
|
|
|
# |
# Process the delbalcookie command. This command deletes a balancer |
# Process the delbalcookie command. This command deletes a balancer |
# cookie in the lonBalancedir directory created by switchserver |
# cookie in the lonBalancedir directory on a load balancer node. |
# |
# |
# Parameters: |
# Parameters: |
# $cmd - Command that got us here. |
# $cmd - Command that got us here. |
Line 5250 sub del_balcookie_handler {
|
Line 5293 sub del_balcookie_handler {
|
my $userinput= "$cmd:$cookie"; |
my $userinput= "$cmd:$cookie"; |
|
|
chomp($cookie); |
chomp($cookie); |
|
$cookie = &unescape($cookie); |
my $deleted = ''; |
my $deleted = ''; |
if ($cookie =~ /^$LONCAPA::match_domain\_$LONCAPA::match_username\_[a-f0-9]{32}$/) { |
if ($cookie =~ /^$LONCAPA::match_domain\_$LONCAPA::match_username\_[a-f0-9]{32}$/) { |
my $execdir=$perlvar{'lonBalanceDir'}; |
my $execdir=$perlvar{'lonBalanceDir'}; |
Line 5465 sub validate_instcode_handler {
|
Line 5509 sub validate_instcode_handler {
|
} |
} |
®ister_handler("autovalidateinstcode", \&validate_instcode_handler, 0, 1, 0); |
®ister_handler("autovalidateinstcode", \&validate_instcode_handler, 0, 1, 0); |
|
|
|
# |
|
# Validate co-owner for cross-listed institutional code and |
|
# institutional course code itself used for a LON-CAPA course. |
|
# |
|
# Formal Parameters: |
|
# $cmd - The command request that got us dispatched. |
|
# $tail - The tail of the command. In this case, |
|
# this is a colon separated string containing: |
|
# $dom - Course's LON-CAPA domain |
|
# $instcode - Institutional course code for the course |
|
# $inst_xlist - Institutional course Id for the crosslisting |
|
# $coowner - Username of co-owner |
|
# (values for all but $dom have been escaped). |
|
# |
|
# $client - Socket open on the client. |
|
# Returns: |
|
# 1 - Indicating processing should continue. |
|
# |
|
sub validate_instcrosslist_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
my $userinput = "$cmd:$tail"; |
|
my ($dom,$instcode,$inst_xlist,$coowner) = split(/:/,$tail); |
|
$instcode = &unescape($instcode); |
|
$inst_xlist = &unescape($inst_xlist); |
|
$coowner = &unescape($coowner); |
|
my $outcome = &localenroll::validate_crosslist_access($dom,$instcode, |
|
$inst_xlist,$coowner); |
|
&Reply($client, \$outcome, $userinput); |
|
|
|
return 1; |
|
} |
|
®ister_handler("autovalidateinstcrosslist", \&validate_instcrosslist_handler, 0, 1, 0); |
|
|
# Get the official sections for which auto-enrollment is possible. |
# Get the official sections for which auto-enrollment is possible. |
# Since the admin people won't know about 'unofficial sections' |
# Since the admin people won't know about 'unofficial sections' |
# we cannot auto-enroll on them. |
# we cannot auto-enroll on them. |
Line 5589 sub validate_class_access_handler {
|
Line 5666 sub validate_class_access_handler {
|
®ister_handler("autovalidateclass_sec", \&validate_class_access_handler, 0, 1, 0); |
®ister_handler("autovalidateclass_sec", \&validate_class_access_handler, 0, 1, 0); |
|
|
# |
# |
|
# Modify institutional sections (using customized &instsec_reformat() |
|
# routine in localenroll.pm), to either clutter or declutter, for |
|
# purposes of ensuring an institutional course section (string) can |
|
# be unambiguously separated into institutional course and section. |
|
# |
|
# Formal Parameters: |
|
# $cmd - The command request that got us dispatched. |
|
# $tail - The tail of the command. In this case this is a colon separated |
|
# set of values that will be split into: |
|
# $cdom - The LON-CAPA domain of the course. |
|
# $action - Either: clutter or declutter |
|
# clutter adds character(s) to eliminate ambiguity |
|
# declutter removes the added characters (e.g., for |
|
# display of the institutional course section string. |
|
# $info - A frozen hash in which keys are: |
|
# LON-CAPA course number:Institutional course code |
|
# and values are a reference to an array of the |
|
# items to modify -- either institutional sections, |
|
# or institutional course sections (for crosslistings). |
|
# $client - The socket open on the client. |
|
# Returns: |
|
# 1 - continue processing. |
|
# |
|
|
|
sub instsec_reformat_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
my $userinput = "$cmd:$tail"; |
|
my ($cdom,$action,$info) = split(/:/,$tail); |
|
my $instsecref = &Apache::lonnet::thaw_unescape($info); |
|
my ($outcome,$result); |
|
eval { |
|
local($SIG{__DIE__})='DEFAULT'; |
|
$outcome=&localenroll::instsec_reformat($cdom,$action,$instsecref); |
|
if ($outcome eq 'ok') { |
|
if (ref($instsecref) eq 'HASH') { |
|
foreach my $key (keys(%{$instsecref})) { |
|
$result .= &escape($key).'='.&Apache::lonnet::freeze_escape($instsecref->{$key}).'&'; |
|
} |
|
$result =~ s/\&$//; |
|
} |
|
} |
|
}; |
|
if (!$@) { |
|
if ($outcome eq 'ok') { |
|
&Reply( $client, \$result, $userinput); |
|
} else { |
|
&Reply($client,\$outcome, $userinput); |
|
} |
|
} else { |
|
&Failure($client,"unknown_cmd\n",$userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("autoinstsecreformat",\&instsec_reformat_handler, 0, 1, 0); |
|
|
|
# |
# Validate course owner or co-owners(s) access to enrollment data for all sections |
# Validate course owner or co-owners(s) access to enrollment data for all sections |
# and crosslistings for a particular course. |
# and crosslistings for a particular course. |
# |
# |
Line 7067 sub make_new_child {
|
Line 7200 sub make_new_child {
|
&Authen::Krb5::init_context(); |
&Authen::Krb5::init_context(); |
|
|
my $no_ets; |
my $no_ets; |
if ($dist =~ /^(?:centos|rhes|scientific|oracle)(\d+)$/) { |
if ($dist =~ /^(?:centos|rhes|scientific|oracle|rocky|alma)(\d+)/) { |
if ($1 >= 7) { |
if ($1 >= 7) { |
$no_ets = 1; |
$no_ets = 1; |
} |
} |
Line 7233 sub make_new_child {
|
Line 7366 sub make_new_child {
|
Debug("Main: Got $user_input\n"); |
Debug("Main: Got $user_input\n"); |
$keep_going = &process_request($user_input); |
$keep_going = &process_request($user_input); |
alarm(0); |
alarm(0); |
&status('Listening to '.$clientname." ($keymode)"); |
&status('Listening to '.$clientname." ($keymode)"); |
} |
} |
|
|
# --------------------------------------------- client unknown or fishy, refuse |
# --------------------------------------------- client unknown or fishy, refuse |
Line 7249 sub make_new_child {
|
Line 7382 sub make_new_child {
|
|
|
&logthis("<font color='red'>CRITICAL: " |
&logthis("<font color='red'>CRITICAL: " |
."Disconnect from $clientip ($clientname)</font>"); |
."Disconnect from $clientip ($clientname)</font>"); |
|
|
|
|
# this exit is VERY important, otherwise the child will become |
# this exit is VERY important, otherwise the child will become |
# a producer of more and more children, forking yourself into |
# a producer of more and more children, forking yourself into |
# process death. |
# process death. |