[LON-CAPA-cvs] cvs: loncom(version_2_10_X) /lonnet/perl lonnet.pm
raeburn
raeburn@source.lon-capa.org
Tue, 17 Aug 2010 00:19:24 -0000
This is a MIME encoded message
--raeburn1282004364
Content-Type: text/plain
raeburn Tue Aug 17 00:19:24 2010 EDT
Modified files: (Branch: version_2_10_X)
/loncom/lonnet/perl lonnet.pm
Log:
- Backport 1.1071, 1.1072, 1.1073, 1.1074, 1.1076, 1.1077, 1.1078.
--raeburn1282004364
Content-Type: text/plain
Content-Disposition: attachment; filename="raeburn-20100817001924.txt"
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1056.4.2 loncom/lonnet/perl/lonnet.pm:1.1056.4.3
--- loncom/lonnet/perl/lonnet.pm:1.1056.4.2 Wed May 26 17:14:43 2010
+++ loncom/lonnet/perl/lonnet.pm Tue Aug 17 00:19:24 2010
@@ -1,7 +1,7 @@
# The LearningOnline Network
# TCP networking package
#
-# $Id: lonnet.pm,v 1.1056.4.2 2010/05/26 17:14:43 raeburn Exp $
+# $Id: lonnet.pm,v 1.1056.4.3 2010/08/17 00:19:24 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -76,7 +76,7 @@
use Image::Magick;
use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir
- $_64bit %env %protocol);
+ $_64bit %env %protocol %loncaparevs %serverhomeIDs);
my (%badServerCache, $memcache, %courselogs, %accesshash, %domainrolehash,
%userrolehash, $processmarker, $dumpcount, %coursedombuf,
@@ -196,7 +196,7 @@
}
sub get_server_loncaparev {
- my ($dom,$lonhost) = @_;
+ my ($dom,$lonhost,$ignore_cache,$caller) = @_;
if (defined($lonhost)) {
if (!defined(&hostname($lonhost))) {
undef($lonhost);
@@ -211,15 +211,74 @@
}
}
if (defined($lonhost)) {
- my $cachetime = 24*3600;
- my ($loncaparev,$cached)=&is_cached_new('serverloncaparev',$lonhost);
+ my $cachetime = 12*3600;
+ if (!$ignore_cache) {
+ my ($loncaparev,$cached)=&is_cached_new('serverloncaparev',$lonhost);
+ if (defined($cached)) {
+ return $loncaparev;
+ }
+ }
+ my ($answer,$loncaparev);
+ my @ids=¤t_machine_ids();
+ if (grep(/^\Q$lonhost\E$/,@ids)) {
+ $answer = $perlvar{'lonVersion'};
+ if ($answer =~ /^[\'\"]?([\d.\-]+)[\'\"]?$/) {
+ $loncaparev = $1;
+ }
+ } else {
+ $answer = &reply('serverloncaparev',$lonhost);
+ if (($answer eq 'unknown_cmd') || ($answer eq 'con_lost')) {
+ if ($caller eq 'loncron') {
+ my $ua=new LWP::UserAgent;
+ $ua->timeout(20);
+ my $protocol = $protocol{$lonhost};
+ $protocol = 'http' if ($protocol ne 'https');
+ my $url = $protocol.'://'.&hostname($lonhost).'/adm/about.html';
+ my $request=new HTTP::Request('GET',$url);
+ my $response=$ua->request($request);
+ unless ($response->is_error()) {
+ my $content = $response->content;
+ if ($content =~ /<p>VERSION\:\s*([\d.\-]+)<\/p>/) {
+ $loncaparev = $1;
+ }
+ }
+ } else {
+ $loncaparev = $loncaparevs{$lonhost};
+ }
+ } elsif ($answer =~ /^[\'\"]?([\d.\-]+)[\'\"]?$/) {
+ $loncaparev = $1;
+ }
+ }
+ return &do_cache_new('serverloncaparev',$lonhost,$loncaparev,$cachetime);
+ }
+}
+
+sub get_server_homeID {
+ my ($hostname,$ignore_cache,$caller) = @_;
+ unless ($ignore_cache) {
+ my ($serverhomeID,$cached)=&is_cached_new('serverhomeID',$hostname);
if (defined($cached)) {
- return $loncaparev;
- } else {
- my $loncaparev = &reply('serverloncaparev',$lonhost);
- return &do_cache_new('serverloncaparev',$lonhost,$loncaparev,$cachetime);
+ return $serverhomeID;
+ }
+ }
+ my $cachetime = 12*3600;
+ my $serverhomeID;
+ if ($caller eq 'loncron') {
+ my @machine_ids = &machine_ids($hostname);
+ foreach my $id (@machine_ids) {
+ my $response = &reply('serverhomeID',$id);
+ unless (($response eq 'unknown_cmd') || ($response eq 'con_lost')) {
+ $serverhomeID = $response;
+ last;
+ }
}
+ if ($serverhomeID eq '') {
+ $serverhomeID = $machine_ids[-1];
+ }
+ } else {
+ $serverhomeID = $serverhomeIDs{$hostname};
}
+ return &do_cache_new('serverhomeID',$hostname,$serverhomeID,$cachetime);
}
# -------------------------------------------------- Non-critical communication
@@ -734,7 +793,7 @@
my $userloadans = &reply('userload',$try_server);
if ($loadans !~ /\d/ && $userloadans !~ /\d/) {
- next; #didn't get a number from the server
+ return; #didn't get a number from the server
}
my $load;
@@ -777,6 +836,27 @@
return 0;
}
+# --------- determine least loaded server in a user's domain which allows login
+
+sub choose_server {
+ my ($udom) = @_;
+ my %domconfhash = &Apache::loncommon::get_domainconf($udom);
+ my %servers = &get_servers($udom);
+ my $lowest_load = 30000;
+ my ($login_host,$hostname);
+ foreach my $lonhost (keys(%servers)) {
+ my $loginvia = $domconfhash{$udom.'.login.loginvia_'.$lonhost};
+ if ($loginvia eq '') {
+ ($login_host, $lowest_load) =
+ &compare_server_load($lonhost, $login_host, $lowest_load);
+ }
+ }
+ if ($login_host ne '') {
+ $hostname = $servers{$login_host};
+ }
+ return ($login_host,$hostname);
+}
+
# --------------------------------------------- Try to change a user's password
sub changepass {
@@ -835,7 +915,7 @@
# --------- Try to authenticate user from domain's lib servers (first this one)
sub authenticate {
- my ($uname,$upass,$udom,$checkdefauth)=@_;
+ my ($uname,$upass,$udom,$checkdefauth,$clientcancheckhost)=@_;
$upass=&escape($upass);
$uname= &LONCAPA::clean_username($uname);
my $uhome=&homeserver($uname,$udom,1);
@@ -858,7 +938,7 @@
return 'no_host';
}
}
- my $answer=reply("encrypt:auth:$udom:$uname:$upass:$checkdefauth",$uhome);
+ my $answer=reply("encrypt:auth:$udom:$uname:$upass:$checkdefauth:$clientcancheckhost",$uhome);
if ($answer eq 'authorized') {
if ($newhome) {
&logthis("User $uname at $udom authorized by $uhome, but needs account");
@@ -876,6 +956,64 @@
return 'no_host';
}
+sub can_host_session {
+ my ($udom,$lonhost,$remoterev,$remotesessions,$hostedsessions) = @_;
+ my $canhost = 1;
+ my $host_idn = &Apache::lonnet::internet_dom($lonhost);
+ if (ref($remotesessions) eq 'HASH') {
+ if (ref($remotesessions->{'excludedomain'}) eq 'ARRAY') {
+ if (grep(/^\Q$host_idn\E$/,@{$remotesessions->{'excludedomain'}})) {
+ $canhost = 0;
+ } else {
+ $canhost = 1;
+ }
+ }
+ if (ref($remotesessions->{'includedomain'}) eq 'ARRAY') {
+ if (grep(/^\Q$host_idn\E$/,@{$remotesessions->{'includedomain'}})) {
+ $canhost = 1;
+ } else {
+ $canhost = 0;
+ }
+ }
+ if ($canhost) {
+ if ($remotesessions->{'version'} ne '') {
+ my ($reqmajor,$reqminor) = ($remotesessions->{'version'} =~ /^(\d+)\.(\d+)$/);
+ if ($reqmajor ne '' && $reqminor ne '') {
+ if ($remoterev =~ /^\'?(\d+)\.(\d+)/) {
+ my $major = $1;
+ my $minor = $2;
+ if (($major < $reqmajor ) ||
+ (($major == $reqmajor) && ($minor < $reqminor))) {
+ $canhost = 0;
+ }
+ } else {
+ $canhost = 0;
+ }
+ }
+ }
+ }
+ }
+ if ($canhost) {
+ if (ref($hostedsessions) eq 'HASH') {
+ if (ref($hostedsessions->{'excludedomain'}) eq 'ARRAY') {
+ if (grep(/^\Q$udom\E$/,@{$hostedsessions->{'excludedomain'}})) {
+ $canhost = 0;
+ } else {
+ $canhost = 1;
+ }
+ }
+ if (ref($hostedsessions->{'includedomain'}) eq 'ARRAY') {
+ if (grep(/^\Q$udom\E$/,@{$hostedsessions->{'includedomain'}})) {
+ $canhost = 1;
+ } else {
+ $canhost = 0;
+ }
+ }
+ }
+ }
+ return $canhost;
+}
+
# ---------------------- Find the homebase for a user from domain's lib servers
my %homecache;
@@ -1352,7 +1490,7 @@
my %domconfig =
&Apache::lonnet::get_dom('configuration',['defaults','quotas',
'requestcourses','inststatus',
- 'coursedefaults'],$domain);
+ 'coursedefaults','usersessions'],$domain);
if (ref($domconfig{'defaults'}) eq 'HASH') {
$domdefaults{'lang_def'} = $domconfig{'defaults'}{'lang_def'};
$domdefaults{'auth_def'} = $domconfig{'defaults'}{'auth_def'};
@@ -1392,6 +1530,14 @@
$domdefaults{$item} = $domconfig{'coursedefaults'}{$item};
}
}
+ if (ref($domconfig{'usersessions'}) eq 'HASH') {
+ if (ref($domconfig{'usersessions'}{'remote'}) eq 'HASH') {
+ $domdefaults{'remotesessions'} = $domconfig{'usersessions'}{'remote'};
+ }
+ if (ref($domconfig{'usersessions'}{'hosted'}) eq 'HASH') {
+ $domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'};
+ }
+ }
&Apache::lonnet::do_cache_new('domdefaults',$domain,\%domdefaults,
$cachetime);
return %domdefaults;
@@ -3059,7 +3205,7 @@
my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,
$coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok,
$selfenrollonly,$catfilter,$showhidden,$caller,$cloner,$cc_clone,
- $cloneonly,$createdbefore,$createdafter,$creationcontext)=@_;
+ $cloneonly,$createdbefore,$createdafter,$creationcontext,$domcloner)=@_;
my $as_hash = 1;
my %returnhash;
if (!$domfilter) { $domfilter=''; }
@@ -3081,7 +3227,8 @@
$showhidden.':'.$caller.':'.&escape($cloner).':'.
&escape($cc_clone).':'.$cloneonly.':'.
&escape($createdbefore).':'.&escape($createdafter).':'.
- &escape($creationcontext),$tryserver);
+ &escape($creationcontext).':'.$domcloner,
+ $tryserver);
my @pairs=split(/\&/,$rep);
foreach my $item (@pairs) {
my ($key,$value)=split(/\=/,$item,2);
@@ -3905,9 +4052,10 @@
my ($domain,$username,$authhost)=@_;
my $now=time;
my %userroles = ('user.login.time' => $now);
- my $rolesdump=reply("dump:$domain:$username:roles",$authhost);
+ my $extra = &freeze_escape({'clientcheckrole' => 1});
+ my $rolesdump=reply("dump:$domain:$username:roles:.::$extra",$authhost);
if (($rolesdump eq 'con_lost') || ($rolesdump eq '') ||
- ($rolesdump =~ /^error:/)) {
+ ($rolesdump =~ /^error:/)) {
return \%userroles;
}
my %allroles=();
@@ -9861,6 +10009,14 @@
my @uniq = grep(!$seen{$_}++, values(%hostdom));
return @uniq;
}
+
+ sub internet_dom {
+ &load_hosts_tab() if (!$loaded);
+
+ my ($lonid) = @_;
+ return $internetdom{$lonid};
+ }
+
}
{
@@ -9978,6 +10134,40 @@
return undef;
}
+ sub get_internet_names {
+ my ($lonid) = @_;
+ return if ($lonid eq '');
+ my ($idnref,$cached)=
+ &Apache::lonnet::is_cached_new('internetnames',$lonid);
+ if ($cached) {
+ return $idnref;
+ }
+ my $ip = &get_host_ip($lonid);
+ my @hosts = &get_hosts_from_ip($ip);
+ my %iphost = &get_iphost();
+ my (@idns,%seen);
+ foreach my $id (@hosts) {
+ my $dom = &host_domain($id);
+ my $prim_id = &domain($dom,'primary');
+ my $prim_ip = &get_host_ip($prim_id);
+ next if ($seen{$prim_ip});
+ if (ref($iphost{$prim_ip}) eq 'ARRAY') {
+ foreach my $id (@{$iphost{$prim_ip}}) {
+ my $intdom = &internet_dom($id);
+ unless (grep(/^\Q$intdom\E$/,@idns)) {
+ push(@idns,$intdom);
+ }
+ }
+ }
+ $seen{$prim_ip} = 1;
+ }
+ return &Apache::lonnet::do_cache_new('internetnames',$lonid,\@idns,12*60*60);
+ }
+
+}
+
+sub all_loncaparevs {
+ return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10);
}
BEGIN {
@@ -10055,6 +10245,34 @@
close($config);
}
+# ---------------------------------------------------------- Read loncaparev table
+{
+ if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") {
+ if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) {
+ while (my $configline=<$config>) {
+ chomp($configline);
+ my ($hostid,$loncaparev)=split(/:/,$configline);
+ $loncaparevs{$hostid}=$loncaparev;
+ }
+ close($config);
+ }
+ }
+}
+
+# ---------------------------------------------------------- Read serverhostID table
+{
+ if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") {
+ if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) {
+ while (my $configline=<$config>) {
+ chomp($configline);
+ my ($name,$id)=split(/:/,$configline);
+ $serverhomeIDs{$name}=$id;
+ }
+ close($config);
+ }
+ }
+}
+
# ------------- set up temporary directory
{
$tmpdir = $perlvar{'lonDaemons'}.'/tmp/';
@@ -10285,9 +10503,14 @@
=item *
X<authenticate()>
-B<authenticate($uname,$upass,$udom)>: try to
+B<authenticate($uname,$upass,$udom,$checkdefauth,$clientcancheckhost)>: try to
authenticate user from domain's lib servers (first use the current
one). C<$upass> should be the users password.
+$checkdefauth is optional (value is 1 if a check should be made to
+ authenticate user using default authentication method, and allow
+ account creation if username does not have account in the domain).
+$clientcancheckhost is optional (value is 1 if checking whether the
+ server can host will occur on the client side in lonauth.pm).
=item *
X<homeserver()>
--raeburn1282004364--