Diff for /loncom/auth/lonlogin.pm between versions 1.158.2.2 and 1.201

version 1.158.2.2, 2015/03/06 22:36:56 version 1.201, 2022/06/30 21:04:13
Line 1 Line 1
 # The LearningOnline Network  # The LearningOnline Network
 # Login Screen  # Login Screen
 #  #
 # $Id$  # $Id$
 #  #
 # Copyright Michigan State University Board of Trustees  # Copyright Michigan State University Board of Trustees
 #  #
 # This file is part of the LearningOnline Network with CAPA (LON-CAPA).  # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
 #  #
 # LON-CAPA is free software; you can redistribute it and/or modify  # LON-CAPA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by  # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2 of the License, or  # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.  # (at your option) any later version.
 #  #
 # LON-CAPA is distributed in the hope that it will be useful,  # LON-CAPA is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of  # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.  # GNU General Public License for more details.
 #  #
 # You should have received a copy of the GNU General Public License  # You should have received a copy of the GNU General Public License
 # along with LON-CAPA; if not, write to the Free Software  # along with LON-CAPA; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #  #
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
   
 package Apache::lonlogin;  package Apache::lonlogin;
   
 use strict;  use strict;
 use Apache::Constants qw(:common);  use Apache::Constants qw(:common);
 use Apache::File ();  use Apache::File ();
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonauth();  use Apache::lonauth();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::migrateuser();  use Apache::migrateuser();
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use LONCAPA;  use LONCAPA qw(:DEFAULT :match);
    use URI::Escape;
 sub handler {  use HTML::Entities();
     my $r = shift;  use CGI::Cookie();
    
     &Apache::loncommon::get_unprocessed_cgi  sub handler {
  (join('&',$ENV{'QUERY_STRING'},$env{'request.querystring'},      my $r = shift;
       $ENV{'REDIRECT_QUERY_STRING'}),  
  ['interface','username','domain','firsturl','localpath','localres',      &Apache::loncommon::get_unprocessed_cgi
   'token','role','symb','iptoken']);   (join('&',$ENV{'QUERY_STRING'},$env{'request.querystring'},
     if (!defined($env{'form.firsturl'})) {        $ENV{'REDIRECT_QUERY_STRING'}),
         &Apache::lonacc::get_posted_cgi($r,['firsturl']);   ['interface','username','domain','firsturl','localpath','localres',
     }    'token','role','symb','iptoken','btoken','ltoken','ttoken','linkkey',
             'saml','sso','retry']);
 # -- check if they are a migrating user  
     if (defined($env{'form.token'})) {  # -- check if they are a migrating user
  return &Apache::migrateuser::handler($r);      if (defined($env{'form.token'})) {
     }          return &Apache::migrateuser::handler($r);
       }
     &Apache::loncommon::no_cache($r);  
     &Apache::lonlocal::get_language_handle($r);      my $lonhost = $r->dir_config('lonHostID');
     &Apache::loncommon::content_type($r,'text/html');      if ($env{'form.ttoken'}) {
     $r->send_http_header;          my %info = &Apache::lonnet::tmpget($env{'form.ttoken'});
     return OK if $r->header_only;          &Apache::lonnet::tmpdel($env{'form.ttoken'});
           if ($info{'origurl'}) {
               $env{'form.firsturl'} = $info{'origurl'};
 # Are we re-routing?          }
     my $londocroot = $r->dir_config('lonDocRoot');           if ($info{'ltoken'}) {
     if (-e "$londocroot/lon-status/reroute.txt") {              $env{'form.ltoken'} = $info{'ltoken'};
  &Apache::lonauth::reroute($r);          } elsif ($info{'linkprot'}) {
  return OK;              $env{'form.linkprot'} = $info{'linkprot'};
     }              foreach my $item ('linkprotuser','linkprotexit') {
                   if ($info{$item} ne '') {
     $env{'form.firsturl'} =~ s/(`)/'/g;                      $env{'form.'.$item} = $info{$item};
                   }
 # -------------------------------- Prevent users from attempting to login twice              }
     my $handle = &Apache::lonnet::check_for_valid_session($r);          } elsif ($info{'linkkey'} ne '') {
     if ($handle ne '') {              $env{'form.linkkey'} = $info{'linkkey'};
         my $lonidsdir=$r->dir_config('lonIDsDir');          }
         if ($handle=~/^publicuser\_/) {      } elsif (($env{'form.sso'}) || ($env{'form.retry'})) {
 # For "public user" - remove it, we apparently really want to login          my $infotoken;
     unlink($r->dir_config('lonIDsDir')."/$handle.id");          if ($env{'form.sso'}) {
         } else {              $infotoken = $env{'form.sso'};
 # Indeed, a valid token is found          } else {
             &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);              $infotoken = $env{'form.retry'};
     my $start_page =           }
         &Apache::loncommon::start_page('Already logged in');          my $data = &Apache::lonnet::reply('tmpget:'.$infotoken,$lonhost);
     my $end_page =           unless (($data=~/^error/) || ($data eq 'con_lost') ||
         &Apache::loncommon::end_page();                  ($data eq 'no_such_host')) {
             my $dest = '/adm/roles';              my %info = &decode_token($data);
             if ($env{'form.firsturl'} ne '') {              foreach my $item (keys(%info)) {
                 $dest = $env{'form.firsturl'};                   $env{'form.'.$item} = $info{$item};
             }              }
     $r->print(              &Apache::lonnet::tmpdel($infotoken);
                   $start_page          }
                  .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'      } else {
                  .'<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].',          if (!defined($env{'form.firsturl'})) {
                   '<a href="'.$dest.'">','</a>','<a href="/adm/logout">','</a>').'</p>'              &Apache::lonacc::get_posted_cgi($r,['firsturl']);
                  .$end_page          }
                  );          if (!defined($env{'form.firsturl'})) {
             return OK;              if ($ENV{'REDIRECT_URL'} =~ m{^/+tiny/+$LONCAPA::match_domain/+\w+$}) {
         }                  $env{'form.firsturl'} = $ENV{'REDIRECT_URL'};
     }              }
           }
 # ---------------------------------------------------- No valid token, continue          if (($env{'form.firsturl'} =~ m{^/+tiny/+$LONCAPA::match_domain/+\w+$}) &&
               (!$env{'form.ltoken'}) && (!$env{'form.linkprot'}) && (!$env{'form.linkkey'})) {
 # ---------------------------- Not possible to really login to domain "public"              &Apache::lonacc::get_posted_cgi($r,['linkkey']);
     if ($env{'form.domain'} eq 'public') {          }
  $env{'form.domain'}='';          if ($env{'form.firsturl'} eq '/adm/logout') {
  $env{'form.username'}='';              delete($env{'form.firsturl'});
     }          }
       }
 # ------ Is this page requested because /adm/migrateuser detected an IP change?  
     my %sessiondata;  # For "public user" - remove any exising "public" cookie, as user really wants to log-in
     if ($env{'form.iptoken'}) {      my ($handle,$lonidsdir,$expirepub,$userdom);
         %sessiondata = &Apache::lonnet::tmpget($env{'form.iptoken'});      $lonidsdir=$r->dir_config('lonIDsDir');
         unless ($sessiondata{'sessionserver'}) {      unless ($r->header_only) {
             my $delete = &Apache::lonnet::tmpdel($env{'form.iptoken'});          $handle = &Apache::lonnet::check_for_valid_session($r,'lonID',undef,\$userdom);
             delete($env{'form.iptoken'});          if ($handle ne '') {
         }              if ($handle=~/^publicuser\_/) {
     }                  unlink($r->dir_config('lonIDsDir')."/$handle.id");
 # ----------------------------------------------------------- Process Interface                  undef($handle);
     $env{'form.interface'}=~s/\W//g;                  undef($userdom);
                   $expirepub = 1;
     (undef,undef,undef,undef,undef,undef,my $clientmobile) =              }
         &Apache::loncommon::decode_user_agent();          }
       }
     my $iconpath=   
  &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));      &Apache::loncommon::no_cache($r);
       &Apache::lonlocal::get_language_handle($r);
     my $lonhost = $r->dir_config('lonHostID');      &Apache::loncommon::content_type($r,'text/html');
     my $domain = &Apache::lonnet::default_login_domain();      if ($expirepub) {
     if ($lonhost ne '') {          my $c = new CGI::Cookie(-name    => 'lonPubID',
         unless ($sessiondata{'sessionserver'}) {                                  -value   => '',
             my $redirect = &check_loginvia($domain,$lonhost);                                  -expires => '-10y',);
             if ($redirect) {          $r->header_out('Set-cookie' => $c);
                 $r->print($redirect);      } elsif (($handle eq '') && ($userdom ne '')) {
                 return OK;          my %cookies=CGI::Cookie->parse($r->header_in('Cookie'));
             }          foreach my $name (keys(%cookies)) {
         }              next unless ($name =~ /^lon(|S|Link|Pub)ID$/);
     }              my $c = new CGI::Cookie(-name    => $name,
                                       -value   => '',
     if (($sessiondata{'domain'}) &&                                      -expires => '-10y',);
         (&Apache::lonnet::domain($env{'form.domain'},'description'))) {              $r->headers_out->add('Set-cookie' => $c);
         $domain=$sessiondata{'domain'};          }
     } elsif (($env{'form.domain'}) &&       }
  (&Apache::lonnet::domain($env{'form.domain'},'description'))) {      $r->send_http_header;
  $domain=$env{'form.domain'};      return OK if $r->header_only;
     }  
   
     my $role    = $r->dir_config('lonRole');  # Are we re-routing?
     my $loadlim = $r->dir_config('lonLoadLim');      my $londocroot = $r->dir_config('lonDocRoot');
     my $uloadlim= $r->dir_config('lonUserLoadLim');      if (-e "$londocroot/lon-status/reroute.txt") {
     my $servadm = $r->dir_config('lonAdmEMail');   &Apache::lonauth::reroute($r);
     my $tabdir  = $r->dir_config('lonTabDir');   return OK;
     my $include = $r->dir_config('lonIncludes');      }
     my $expire  = $r->dir_config('lonExpire');  
     my $version = $r->dir_config('lonVersion');  # Check if browser sent a LON-CAPA load balancer cookie (and this is a balancer)
     my $host_name = &Apache::lonnet::hostname($lonhost);  
       my ($found_server,$balancer_cookie) = &Apache::lonnet::check_for_balancer_cookie($r,1);
 # --------------------------------------------- Default values for login fields      if ($found_server) {
               my $hostname = &Apache::lonnet::hostname($found_server);
     my ($authusername,$authdomain);          if ($hostname ne '') {
     if ($sessiondata{'username'}) {              my $protocol = $Apache::lonnet::protocol{$found_server};
         $authusername=$sessiondata{'username'};              $protocol = 'http' if ($protocol ne 'https');
     } else {              my $dest = '/adm/roles';
         $env{'form.username'} = &Apache::loncommon::cleanup_html($env{'form.username'});              if ($env{'form.firsturl'} ne '') {
         $authusername=($env{'form.username'}?$env{'form.username'}:'');                  $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
     }              }
     if ($sessiondata{'domain'}) {              my %info = (
         $authdomain=$sessiondata{'domain'};                           balcookie => $lonhost.':'.$balancer_cookie,
     } else {                         );
         $env{'form.domain'} = &Apache::loncommon::cleanup_html($env{'form.domain'});              if ($env{'form.role'}) {
         $authdomain=($env{'form.domain'}?$env{'form.domain'}:$domain);                  $info{'role'} = $env{'form.role'};
     }              }
               if ($env{'form.symb'}) {
 # ---------------------------------------------------------- Determine own load                  $info{'symb'} = $env{'form.symb'};
     my $loadavg;              }
     {              my $balancer_token = &Apache::lonnet::tmpput(\%info,$found_server);
  my $loadfile=Apache::File->new('/proc/loadavg');              unless (($balancer_token eq 'con_lost') || ($balancer_token eq 'refused') ||
  $loadavg=<$loadfile>;                      ($balancer_token eq 'unknown_cmd') || ($balancer_token eq 'no_such_host')) {
     }                  $dest .=  (($dest=~/\?/)?'&amp;':'?') . 'btoken='.$balancer_token;
     $loadavg =~ s/\s.*//g;              }
               if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
     my ($loadpercent,$userloadpercent);                  my %link_info;
     if ($loadlim) {                  if ($env{'form.ltoken'}) {
         $loadpercent=sprintf("%.1f",100*$loadavg/$loadlim);                      $link_info{'ltoken'} = $env{'form.ltoken'};
     }                  } elsif ($env{'form.linkprot'}) {
     if ($uloadlim) {                      $link_info{'linkprot'} = $env{'form.linkprot'};
         $userloadpercent=&Apache::lonnet::userload();                      foreach my $item ('linkprotuser','linkprotexit') {
     }                          if ($env{'form.'.$item} ne '') {
                               $link_info{$item} = $env{'form.'.$item};
     my $firsturl=                          }
     ($env{'request.firsturl'}?$env{'request.firsturl'}:$env{'form.firsturl'});                      }
                   } elsif ($env{'form.linkkey'} ne '') {
 # ----------------------------------------------------------- Get announcements                      $link_info{'linkkey'} = $env{'form.linkkey'};
     my $announcements=&Apache::lonnet::getannounce();                  }
 # -------------------------------------------------------- Set login parameters                  if (keys(%link_info)) {
                       $link_info{'origurl'} = $env{'form.firsturl'};
     my @hexstr=('0','1','2','3','4','5','6','7',                      my $token = &Apache::lonnet::tmpput(\%link_info,$found_server,'link');
                 '8','9','a','b','c','d','e','f');                      unless (($token eq 'con_lost') || ($token eq 'refused') ||
     my $lkey='';                              ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
     for (0..7) {                          $dest .=  (($dest=~/\?/)?'&amp;':'?') . 'ttoken='.$token;
         $lkey.=$hexstr[rand(15)];                      }
     }                  }
               }
     my $ukey='';              unless ($found_server eq $lonhost) {
     for (0..7) {                  my $alias = &Apache::lonnet::use_proxy_alias($r,$found_server);
         $ukey.=$hexstr[rand(15)];                  $hostname = $alias if ($alias ne '');
     }              }
               my $url = $protocol.'://'.$hostname.$dest;
     my $lextkey=hex($lkey);              my $start_page =
     if ($lextkey>2147483647) { $lextkey-=4294967296; }                  &Apache::loncommon::start_page('Switching Server ...',undef,
                                                  {'redirect'       => [0,$url],});
     my $uextkey=hex($ukey);              my $end_page   = &Apache::loncommon::end_page();
     if ($uextkey>2147483647) { $uextkey-=4294967296; }              $r->print($start_page.$end_page);
               return OK;
 # -------------------------------------------------------- Store away log token          }
     my $tokenextras;      }
     if ($env{'form.role'}) {  
         $tokenextras = '&role='.&escape($env{'form.role'});  #
     }  # Check if a LON-CAPA load balancer sent user here because user's browser sent
     if ($env{'form.symb'}) {  # it a balancer cookie for an active session on this server.
         if (!$tokenextras) {  #
             $tokenextras = '&';  
         }      my $balcookie;
         $tokenextras .= '&symb='.&escape($env{'form.symb'});      if ($env{'form.btoken'}) {
     }          my %info = &Apache::lonnet::tmpget($env{'form.btoken'});
     if ($env{'form.iptoken'}) {          $balcookie = $info{'balcookie'};
         if (!$tokenextras) {          &Apache::lonnet::tmpdel($env{'form.btoken'});
             $tokenextras = '&&';          delete($env{'form.btoken'});
         }      }
         $tokenextras .= '&iptoken='.&escape($env{'form.iptoken'});  
     }  #
     my $logtoken=Apache::lonnet::reply(  # If browser sent an old cookie for which the session file had been removed
        'tmpput:'.$ukey.$lkey.'&'.$firsturl.$tokenextras,  # check if configuration for user's domain has a portal URL set.  If so
        $lonhost);  # switch user's log-in to the portal.
   #
 # -- If we cannot talk to ourselves, or hostID does not map to a hostname  
 #    we are in serious trouble      if (($handle eq '') && ($userdom ne '')) {
           my %domdefaults = &Apache::lonnet::get_domain_defaults($userdom);
     if (($logtoken eq 'con_lost') || ($logtoken eq 'no_such_host')) {          if ($domdefaults{'portal_def'} =~ /^https?\:/) {
         if ($logtoken eq 'no_such_host') {              my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,
             &Apache::lonnet::logthis('No valid logtoken for log-in page -- unable to determine hostname for hostID: '.$lonhost.'. Check entry in hosts.tab');                                            {'redirect' => [0,$domdefaults{'portal_def'}],});
         }              my $end_page   = &Apache::loncommon::end_page();
         my $spares='';              $r->print($start_page.$end_page);
  my $last;              return OK;
         foreach my $hostid (sort          }
     {      }
  &Apache::lonnet::hostname($a) cmp  
     &Apache::lonnet::hostname($b);  # -------------------------------- Prevent users from attempting to login twice
     }      if ($handle ne '') {
     keys(%Apache::lonnet::spareid)) {          &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);
             next if ($hostid eq $lonhost);   my $start_page =
     my $hostname = &Apache::lonnet::hostname($hostid);      &Apache::loncommon::start_page('Already logged in');
     next if (($last eq $hostname) || ($hostname eq ''));   my $end_page =
             $spares.='<br /><font size="+1"><a href="http://'.      &Apache::loncommon::end_page();
                 $hostname.          my $dest = '/adm/roles';
                 '/adm/login?domain='.$authdomain.'">'.          if ($env{'form.firsturl'} ne '') {
                 $hostname.'</a>'.              $dest = &HTML::Entities::encode($env{'form.firsturl'},'\'"<>&');
                 ' '.&mt('(preferred)').'</font>'.$/;          }
     $last=$hostname;          if (($env{'form.ltoken'}) || ($env{'form.linkprot'})) {
         }              my ($linkprot,$linkprotuser,$linkprotexit);
         if ($spares) {              if ($env{'form.ltoken'}) {
             $spares.= '<br />';                  my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
         }                  $linkprot = $info{'linkprot'};
         my %all_hostnames = &Apache::lonnet::all_hostnames();                  if ($info{'linkprotuser'} ne '') {
         foreach my $hostid (sort                      $linkprotuser = $info{'linkprotuser'};
     {                  }
  &Apache::lonnet::hostname($a) cmp                  if ($info{'linkprotexit'} ne '') {
     &Apache::lonnet::hostname($b);                      $linkprotexit = $info{'linkprotexit'};
     }                  }
     keys(%all_hostnames)) {              } else {
             next if ($hostid eq $lonhost || $Apache::lonnet::spareid{$hostid});                  $linkprot = $env{'form.linkprot'};
             my $hostname = &Apache::lonnet::hostname($hostid);                  $linkprotuser = $env{'form.linkprotuser'};
             next if (($last eq $hostname) || ($hostname eq ''));                  $linkprotexit = $env{'form.linkprotexit'};
             $spares.='<br /><a href="http://'.              }
              $hostname.              if ($linkprot) {
              '/adm/login?domain='.$authdomain.'">'.                  my ($linkprotector,$deeplink) = split(/:/,$linkprot,2);
              $hostname.'</a>';                  if (($deeplink =~ m{^/tiny/$match_domain/\w+$}) &&
             $last=$hostname;                      ($linkprotuser ne '') && ($linkprotuser ne $env{'user.name'}.':'.$env{'user.domain'})) {
          }                      my $ip = &Apache::lonnet::get_requestor_ip();
          $r->print(                      my %linkprotinfo = (
    '<html>'                                            origurl => $deeplink,
   .'<head><title>'                                            linkprot => $linkprot,
   .&mt('The LearningOnline Network with CAPA')                                            linkprotuser => $linkprotuser,
   .'</title></head>'                                            linkprotexit => $linkprotexit,
   .'<body bgcolor="#FFFFFF">'                                         );    
   .'<h1>'.&mt('The LearningOnline Network with CAPA').'</h1>'                      if ($env{'form.ltoken'}) {
   .'<img src="/adm/lonKaputt/lonlogo_broken.gif" align="right" />'                          my $delete = &Apache::lonnet::tmpdel($env{'form.ltoken'});
   .'<h3>'.&mt('This LON-CAPA server is temporarily not available for login.').'</h3>');                      }
         if ($spares) {                      &Apache::migrateuser::logout($r,$ip,$handle,undef,undef,\%linkprotinfo);
             $r->print('<p>'.&mt('Please attempt to login to one of the following servers:')                      return OK;
                      .'</p>'                  }
                      .$spares);                  if ($env{'user.linkprotector'}) {
         }                      my @protectors = split(/,/,$env{'user.linkprotector'});
         $r->print('</body>'                      unless (grep(/^\Q$linkprotector\E$/,@protectors)) {
                  .'</html>'                          push(@protectors,$linkprotector);
         );                          @protectors = sort { $a <=> $b } @protectors;
         return OK;                          &Apache::lonnet::appenv({'user.linkprotector' => join(',',@protectors)});
     }                      }
                   } else {
 # ----------------------------------------------- Apparently we are in business                      &Apache::lonnet::appenv({'user.linkprotector' => $linkprotector });
     $servadm=~s/\,/\<br \/\>/g;                  }
                   if ($env{'user.linkproturi'}) {
 # ----------------------------------------------------------- Front page design                      my @proturis = split(/,/,$env{'user.linkproturi'});
     my $pgbg=&Apache::loncommon::designparm('login.pgbg',$domain);                      unless (grep(/^\Q$deeplink\E$/,@proturis)) {
     my $font=&Apache::loncommon::designparm('login.font',$domain);                          push(@proturis,$deeplink);
     my $link=&Apache::loncommon::designparm('login.link',$domain);                          @proturis = sort @proturis;
     my $vlink=&Apache::loncommon::designparm('login.vlink',$domain);                          &Apache::lonnet::appenv({'user.linkproturi' => join(',',@proturis)});
     my $alink=&Apache::loncommon::designparm('login.alink',$domain);                      }
     my $mainbg=&Apache::loncommon::designparm('login.mainbg',$domain);                  } else {
     my $loginbox_bg=&Apache::loncommon::designparm('login.sidebg',$domain);                      &Apache::lonnet::appenv({'user.linkproturi' => $deeplink});
     my $loginbox_header_bgcol=&Apache::loncommon::designparm('login.bgcol',$domain);                  }
     my $loginbox_header_textcol=&Apache::loncommon::designparm('login.textcol',$domain);              }
     my $logo=&Apache::loncommon::designparm('login.logo',$domain);          } elsif ($env{'form.linkkey'} ne '') {
     my $img=&Apache::loncommon::designparm('login.img',$domain);              if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
     my $domainlogo=&Apache::loncommon::domainlogo($domain);                  my $linkkey = $env{'form.linkkey'};
     my $showbanner = 1;                  if ($env{'user.deeplinkkey'}) {
     my $showmainlogo = 1;                      my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
     if (defined(&Apache::loncommon::designparm('login.showlogo_img',$domain))) {                      unless (grep(/^\Q$linkkey\E$/,@linkkeys)) {
         $showbanner = &Apache::loncommon::designparm('login.showlogo_img',$domain);                          push(@linkkeys,$linkkey);
     }                          &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
     if (defined(&Apache::loncommon::designparm('login.showlogo_logo',$domain))) {                      }
         $showmainlogo = &Apache::loncommon::designparm('login.showlogo_logo',$domain);                  } else {
     }                      &Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
     my $showadminmail;                  }
     my @possdoms = &Apache::lonnet::current_machine_domains();                  my $deeplink = $env{'form.firsturl'};
     if (grep(/^\Q$domain\E$/,@possdoms)) {                  if ($env{'user.keyedlinkuri'}) {
         $showadminmail=&Apache::loncommon::designparm('login.adminmail',$domain);                      my @keyeduris = split(/,/,$env{'user.keyedlinkuri'});
     }                      unless (grep(/^\Q$deeplink\E$/,@keyeduris)) {
     my $showcoursecat =                          push(@keyeduris,$deeplink);
         &Apache::loncommon::designparm('login.coursecatalog',$domain);                          &Apache::lonnet::appenv({'user.keyedlinkuri' => join(',',sort(@keyeduris))});
     my $shownewuserlink =                       }
         &Apache::loncommon::designparm('login.newuser',$domain);                  } else {
     my $showhelpdesk =                      &Apache::lonnet::appenv({'user.keyedlinkuri' => $deeplink});
         &Apache::loncommon::designparm('login.helpdesk',$domain);                  }
     my $now=time;              }
     my $js = (<<ENDSCRIPT);          }
           if ($env{'form.ltoken'}) {
 <script type="text/javascript" language="JavaScript">              my $delete = &Apache::lonnet::tmpdel($env{'form.ltoken'});
 // <![CDATA[          }
 function send()   $r->print(
 {                    $start_page
 this.document.server.elements.uname.value                   .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
 =this.document.client.elements.uname.value;                   .'<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].',
                     '<a href="'.$dest.'">','</a>','<a href="/adm/logout">','</a>').'</p>'
 this.document.server.elements.udom.value                   .$end_page
 =this.document.client.elements.udom.value;                   );
           return OK;
 uextkey=this.document.client.elements.uextkey.value;      }
 lextkey=this.document.client.elements.lextkey.value;  
 initkeys();  # ---------------------------------------------------- No valid token, continue
   
 this.document.server.elements.upass0.value  # ---------------------------- Not possible to really login to domain "public"
     =crypted(this.document.client.elements.upass$now.value.substr(0,15));      if ($env{'form.domain'} eq 'public') {
 this.document.server.elements.upass1.value   $env{'form.domain'}='';
     =crypted(this.document.client.elements.upass$now.value.substr(15,15));   $env{'form.username'}='';
 this.document.server.elements.upass2.value      }
     =crypted(this.document.client.elements.upass$now.value.substr(30,15));  
   # ------ Is this page requested because /adm/migrateuser detected an IP change?
 this.document.client.elements.uname.value='';      my %sessiondata;
 this.document.client.elements.upass$now.value='';      if ($env{'form.iptoken'}) {
           %sessiondata = &Apache::lonnet::tmpget($env{'form.iptoken'});
 this.document.server.submit();          unless ($sessiondata{'sessionserver'}) {
 return false;              my $delete = &Apache::lonnet::tmpdel($env{'form.iptoken'});
 }              delete($env{'form.iptoken'});
           }
 function enableInput() {      }
     this.document.client.elements.upass$now.removeAttribute("readOnly");  # ----------------------------------------------------------- Process Interface
     this.document.client.elements.uname.removeAttribute("readOnly");      $env{'form.interface'}=~s/\W//g;
     this.document.client.elements.udom.removeAttribute("readOnly");  
     return;      (undef,undef,undef,undef,undef,undef,my $clientmobile) =
 }          &Apache::loncommon::decode_user_agent($r);
   
 // ]]>      my $iconpath=
 </script>   &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));
   
 ENDSCRIPT      my $domain = &Apache::lonnet::default_login_domain();
       my $defdom = $domain;
 # --------------------------------------------------- Print login screen header      if ($lonhost ne '') {
           unless ($sessiondata{'sessionserver'}) {
     my %add_entries = (              my $redirect = &check_loginvia($domain,$lonhost,$lonidsdir,$balcookie);
        bgcolor      => "$mainbg",              if ($redirect) {
        text         => "$font",                  $r->print($redirect);
        link         => "$link",                  return OK;
        vlink        => "$vlink",              }
        alink        => "$alink",          }
                onload       => 'javascript:enableInput();',);      }
   
     my %defaultdomconf = &Apache::loncommon::get_domainconf($defdom);      if (($sessiondata{'domain'}) &&
     my $headextra = $defaultdomconf{$defdom.'.login.headtag_'.$lonhost};          (&Apache::lonnet::domain($sessiondata{'domain'},'description'))) {
     my $headextra_exempt = $defaultdomconf{$domain.'.login.headtag_exempt_'.$lonhost};          $domain=$sessiondata{'domain'};
     if ($headextra) {      } elsif (($env{'form.domain'}) &&
         my $omitextra;   (&Apache::lonnet::domain($env{'form.domain'},'description'))) {
         if ($headextra_exempt ne '') {   $domain=$env{'form.domain'};
             my @exempt = split(',',$headextra_exempt);      }
             my $ip = $ENV{'REMOTE_ADDR'};  
             if (grep(/^\Q$ip\E$/,@exempt)) {      my $role    = $r->dir_config('lonRole');
                 $omitextra = 1;      my $loadlim = $r->dir_config('lonLoadLim');
             }      my $uloadlim= $r->dir_config('lonUserLoadLim');
         }      my $servadm = $r->dir_config('lonAdmEMail');
         unless ($omitextra) {      my $tabdir  = $r->dir_config('lonTabDir');
             my $confname = $defdom.'-domainconfig';      my $include = $r->dir_config('lonIncludes');
             if ($headextra =~ m{^\Q/res/$defdom/$confname/login/headtag/$lonhost/\E}) {      my $expire  = $r->dir_config('lonExpire');
                 my $extra = &Apache::lonnet::getfile(&Apache::lonnet::filelocation("",$headextra));      my $version = $r->dir_config('lonVersion');
                 unless ($extra eq '-1') {      my $host_name = &Apache::lonnet::hostname($lonhost);
                     $js .= "\n".$extra."\n";  
                 }  # --------------------------------------------- Default values for login fields
             }     
         }      my ($authusername,$authdomain);
     }      if ($sessiondata{'username'}) {
           $authusername=$sessiondata{'username'};
     $r->print(&Apache::loncommon::start_page('The LearningOnline Network with CAPA Login',$js,      } else {
        { 'redirect'       => [$expire,'/adm/roles'],           $env{'form.username'} = &Apache::loncommon::cleanup_html($env{'form.username'});
  'add_entries' => \%add_entries,          $authusername=($env{'form.username'}?$env{'form.username'}:'');
  'only_body'   => 1,}));      }
       if ($sessiondata{'domain'}) {
 # ----------------------------------------------------------------------- Texts          $authdomain=$sessiondata{'domain'};
       } else {
     my %lt=&Apache::lonlocal::texthash(          $env{'form.domain'} = &Apache::loncommon::cleanup_html($env{'form.domain'});
           'un'       => 'Username',          $authdomain=($env{'form.domain'}?$env{'form.domain'}:$domain);
           'pw'       => 'Password',      }
           'dom'      => 'Domain',  
           'perc'     => 'percent',  # ---------------------------------------------------------- Determine own load
           'load'     => 'Server Load',      my $loadavg;
           'userload' => 'User Load',      {
           'catalog'  => 'Course/Community Catalog',   my $loadfile=Apache::File->new('/proc/loadavg');
           'log'      => 'Log in',   $loadavg=<$loadfile>;
           'help'     => 'Log-in Help',      }
           'serv'     => 'Server',      $loadavg =~ s/\s.*//g;
           'servadm'  => 'Server Administration',  
           'helpdesk' => 'Contact Helpdesk',      my ($loadpercent,$userloadpercent);
           'forgotpw' => 'Forgot password?',      if ($loadlim) {
           'newuser'  => 'New User?',          $loadpercent=sprintf("%.1f",100*$loadavg/$loadlim);
        );      }
 # -------------------------------------------------- Change password field name      if ($uloadlim) {
           $userloadpercent=&Apache::lonnet::userload();
     my $forgotpw = &forgotpwdisplay(%lt);      }
     $forgotpw .= '<br />' if $forgotpw;  
     my $loginhelp = &Apache::lonauth::loginhelpdisplay($authdomain);      my $firsturl=
     if ($loginhelp) {      ($env{'request.firsturl'}?$env{'request.firsturl'}:$env{'form.firsturl'});
         $loginhelp = '<a href="'.$loginhelp.'">'.$lt{'help'}.'</a><br />';  
     }  # ----------------------------------------------------------- Get announcements
       my $announcements=&Apache::lonnet::getannounce();
 # ---------------------------------------------------- Serve out DES JavaScript  # -------------------------------------------------------- Set login parameters
     {  
     my $jsh=Apache::File->new($include."/londes.js");      my @hexstr=('0','1','2','3','4','5','6','7',
     $r->print(<$jsh>);                  '8','9','a','b','c','d','e','f');
     }      my $lkey='';
 # ---------------------------------------------------------- Serve rest of page      for (0..7) {
           $lkey.=$hexstr[rand(15)];
     $r->print(      }
     '<div class="LC_Box"'  
    .' style="margin:0 auto; padding:10px; width:90%; height: auto; background-color:#FFFFFF;">'      my $ukey='';
 );      for (0..7) {
           $ukey.=$hexstr[rand(15)];
     $r->print(<<ENDSERVERFORM);      }
 <form name="server" action="/adm/authenticate" method="post" target="_top">  
    <input type="hidden" name="logtoken" value="$logtoken" />      my $lextkey=hex($lkey);
    <input type="hidden" name="serverid" value="$lonhost" />      if ($lextkey>2147483647) { $lextkey-=4294967296; }
    <input type="hidden" name="uname" value="" />  
    <input type="hidden" name="upass0" value="" />      my $uextkey=hex($ukey);
    <input type="hidden" name="upass1" value="" />      if ($uextkey>2147483647) { $uextkey-=4294967296; }
    <input type="hidden" name="upass2" value="" />  
    <input type="hidden" name="udom" value="" />  # -------------------------------------------------------- Store away log token
    <input type="hidden" name="localpath" value="$env{'form.localpath'}" />      my ($tokenextras,$tokentype,$linkprot_for_login);
    <input type="hidden" name="localres" value="$env{'form.localres'}" />      my @names = ('role','symb','iptoken','ltoken','linkprotuser','linkprotexit','linkprot','linkkey');
   </form>      foreach my $name (@names) {
 ENDSERVERFORM          if ($env{'form.'.$name} ne '') {
     my $coursecatalog;              if ($name eq 'ltoken') {
     if (($showcoursecat eq '') || ($showcoursecat)) {                  my %info = &Apache::lonnet::tmpget($env{'form.'.$name});
         $coursecatalog = &coursecatalog_link($lt{'catalog'}).'<br />';                  if ($info{'linkprot'}) {
     }                      $linkprot_for_login = $info{'linkprot'};
     my $newuserlink;                      $tokenextras .= '&linkprot='.&escape($info{'linkprot'});
     if ($shownewuserlink) {                      foreach my $item ('linkprotuser','linkprotexit') {
         $newuserlink = &newuser_link($lt{'newuser'}).'<br />';                          if ($info{$item}) {
     }                              $tokenextras .= '&'.$item.'='.&escape($info{$item});
     my $logintitle =                          }
         '<h2 class="LC_hcell"'                      }
        .' style="background:'.$loginbox_header_bgcol.';'                      $tokentype = 'link';
        .' color:'.$loginbox_header_textcol.'">'                      last;
        .$lt{'log'}                  }
        .'</h2>';              } else {
                   $tokenextras .= '&'.$name.'='.&escape($env{'form.'.$name});
     my $noscript_warning='<noscript><span class="LC_warning"><b>'                  if (($name eq 'linkkey') || ($name eq 'linkprot')) {
                         .&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.')                      if ((($env{'form.retry'}) || ($env{'form.sso'})) &&
                         .'</b></span></noscript>';                          (!$env{'form.ltoken'}) && ($name eq 'linkprot')) {
     my $helpdeskscript;                          $linkprot_for_login = $env{'form.linkprot'};
     my $contactblock = &contactdisplay(\%lt,$servadm,$showadminmail,                      }
                                        $authdomain,\$helpdeskscript,                      $tokentype = 'link';
                                        $showhelpdesk,\@possdoms);                  }
               }
     my $mobileargs;          }
     if ($clientmobile) {      }
         $mobileargs = 'autocapitalize="off" autocorrect="off"';       if ($tokentype) {
     }          $tokenextras .= ":$tokentype";
     my $loginform=(<<LFORM);      }
 <form name="client" action="" onsubmit="return(send())">      my $logtoken=Apache::lonnet::reply(
   <input type="hidden" name="lextkey" value="$lextkey" />         'tmpput:'.$ukey.$lkey.'&'.&escape($firsturl).$tokenextras,
   <input type="hidden" name="uextkey" value="$uextkey" />         $lonhost);
   <b><label for="uname">$lt{'un'}</label>:</b><br />  
   <input type="text" name="uname" id="uname" size="15" value="$authusername" readonly="readonly" $mobileargs /><br />  # -- If we cannot talk to ourselves, or hostID does not map to a hostname
   <b><label for="upass$now">$lt{'pw'}</label>:</b><br />  #    we are in serious trouble
   <input type="password" name="upass$now" id="upass$now" size="15" readonly="readonly" /><br />  
   <b><label for="udom">$lt{'dom'}</label>:</b><br />      if (($logtoken eq 'con_lost') || ($logtoken eq 'no_such_host')) {
   <input type="text" name="udom" id="udom" size="15" value="$authdomain" readonly="readonly" $mobileargs /><br />          if ($logtoken eq 'no_such_host') {
   <input type="submit" value="$lt{'log'}" />              &Apache::lonnet::logthis('No valid logtoken for log-in page -- unable to determine hostname for hostID: '.$lonhost.'. Check entry in hosts.tab');
 </form>          }
 LFORM          if ($env{'form.ltoken'}) {
               &Apache::lonnet::tmpdel($env{'form.ltoken'});
     if ($showbanner) {              delete($env{'form.ltoken'});
         $r->print(<<HEADER);          }
 <!-- The LON-CAPA Header -->          my $spares='';
 <div style="background:$pgbg;margin:0;width:100%;">          my (@sparehosts,%spareservers);
   <img src="$img" border="0" alt="The Learning Online Network with CAPA" />          my $sparesref = &Apache::lonnet::this_host_spares($defdom);
 </div>          if (ref($sparesref) eq 'HASH') {
 HEADER              foreach my $key (keys(%{$sparesref})) {
     }                  if (ref($sparesref->{$key}) eq 'ARRAY') {
     $r->print(<<ENDTOP);                      my @sorted = sort { &Apache::lonnet::hostname($a) cmp
 <div style="float:left;margin-top:0;">                                          &Apache::lonnet::hostname($b);
 <div class="LC_Box" style="background:$loginbox_bg;">                                        } @{$sparesref->{$key}};
   $logintitle                      if (@sorted) {
   $loginform                          if ($key eq 'primary') {
   $noscript_warning                              unshift(@sparehosts,@sorted);
 </div>                          } elsif ($key eq 'default') {
                                 push(@sparehosts,@sorted);
 <div class="LC_Box" style="padding-top: 10px;">                          }
   $loginhelp                      }
   $forgotpw                  }
   $contactblock              }
   $newuserlink          }
   $coursecatalog          foreach my $hostid (@sparehosts) {
 </div>              next if ($hostid eq $lonhost);
 </div>      my $hostname = &Apache::lonnet::hostname($hostid);
       next if (($hostname eq '') || ($spareservers{$hostname}));
 <div>              $spareservers{$hostname} = 1;
 ENDTOP              my $protocol = $Apache::lonnet::protocol{$hostid};
     if ($showmainlogo) {              $protocol = 'http' if ($protocol ne 'https');
         $r->print(' <img src="'.$logo.'" alt="" />'."\n");              $spares.='<br /><span style="font-size: larger;"><a href="'.$protocol.'://'.
     }                  $hostname.
 $r->print(<<ENDTOP);                  '/adm/login?domain='.$authdomain.'">'.
 $announcements                  $hostname.'</a>'.
 </div>                  ' '.&mt('(preferred)').'</span>'.$/;
 <hr style="clear:both;" />          }
 ENDTOP          if ($spares) {
     my ($domainrow,$serverrow,$loadrow,$userloadrow,$versionrow);              $spares.= '<br />';
     $domainrow = <<"END";          }
       <tr>          my %all_hostnames = &Apache::lonnet::all_hostnames();
        <td  align="left" valign="top">          foreach my $hostid (sort
         <small><b>$lt{'dom'}:&nbsp;</b></small>      {
        </td>   &Apache::lonnet::hostname($a) cmp
        <td  align="left" valign="top">      &Apache::lonnet::hostname($b);
         <small><tt>&nbsp;$domain</tt></small>      }
        </td>      keys(%all_hostnames)) {
       </tr>              next if ($hostid eq $lonhost);
 END              my $hostname = &Apache::lonnet::hostname($hostid);
     $serverrow = <<"END";              next if (($hostname eq '') || ($spareservers{$hostname}));
       <tr>              $spareservers{$hostname} = 1;
        <td  align="left" valign="top">              my $protocol = $Apache::lonnet::protocol{$hostid};
         <small><b>$lt{'serv'}:&nbsp;</b></small>              $protocol = 'http' if ($protocol ne 'https');
        </td>              $spares.='<br /><a href="'.$protocol.'://'.
        <td align="left" valign="top">               $hostname.
         <small><tt>&nbsp;$lonhost ($role)</tt></small>               '/adm/login?domain='.$authdomain.'">'.
        </td>               $hostname.'</a>';
       </tr>           }
 END           $r->print(
     if ($loadlim) {     '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
         $loadrow = <<"END";    .'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'
       <tr>    .'<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>'
        <td align="left" valign="top">    .&mt('The LearningOnline Network with CAPA')
         <small><b>$lt{'load'}:&nbsp;</b></small>    .'</title></head>'
        </td>    .'<body bgcolor="#FFFFFF">'
        <td align="left" valign="top">    .'<h1>'.&mt('The LearningOnline Network with CAPA').'</h1>'
         <small><tt>&nbsp;$loadpercent $lt{'perc'}</tt></small>    .'<img src="/adm/lonKaputt/lonlogo_broken.gif" alt="broken icon" align="right" />'
        </td>    .'<h3>'.&mt('This LON-CAPA server is temporarily not available for login.').'</h3>');
       </tr>          if ($spares) {
 END              $r->print('<p>'.&mt('Please attempt to login to one of the following servers:')
     }                       .'</p>'
     if ($uloadlim) {                       .$spares);
         $userloadrow = <<"END";          }
       <tr>          $r->print('</body>'
        <td align="left" valign="top">                   .'</html>'
         <small><b>$lt{'userload'}:&nbsp;</b></small>          );
        </td>          return OK;
        <td align="left" valign="top">      }
         <small><tt>&nbsp;$userloadpercent $lt{'perc'}</tt></small>  
        </td>  # ----------------------------------------------- Apparently we are in business
       </tr>      $servadm=~s/\,/\<br \/\>/g;
 END  
     }  # ----------------------------------------------------------- Front page design
     if (($version ne '') && ($version ne '<!-- VERSION -->')) {      my $pgbg=&Apache::loncommon::designparm('login.pgbg',$domain);
         $versionrow = <<"END";      my $font=&Apache::loncommon::designparm('login.font',$domain);
       <tr>      my $link=&Apache::loncommon::designparm('login.link',$domain);
        <td colspan="2" align="left">      my $vlink=&Apache::loncommon::designparm('login.vlink',$domain);
         <small>$version</small>      my $alink=&Apache::loncommon::designparm('login.alink',$domain);
        </td>      my $mainbg=&Apache::loncommon::designparm('login.mainbg',$domain);
       </tr>      my $loginbox_bg=&Apache::loncommon::designparm('login.sidebg',$domain);
 END      my $loginbox_header_bgcol=&Apache::loncommon::designparm('login.bgcol',$domain);
     }      my $loginbox_header_textcol=&Apache::loncommon::designparm('login.textcol',$domain);
       my $logo=&Apache::loncommon::designparm('login.logo',$domain);
     $r->print(<<ENDDOCUMENT);      my $img=&Apache::loncommon::designparm('login.img',$domain);
     <div style="float: left;">      my $domainlogo=&Apache::loncommon::domainlogo($domain);
      <table border="0" cellspacing="0" cellpadding="0">      my $showbanner = 1;
 $domainrow      my $showmainlogo = 1;
 $serverrow      if (defined(&Apache::loncommon::designparm('login.showlogo_img',$domain))) {
 $loadrow              $showbanner = &Apache::loncommon::designparm('login.showlogo_img',$domain);
 $userloadrow      }
 $versionrow      if (defined(&Apache::loncommon::designparm('login.showlogo_logo',$domain))) {
      </table>          $showmainlogo = &Apache::loncommon::designparm('login.showlogo_logo',$domain);
     </div>      }
     <div style="float: right;">      my $showadminmail;
     $domainlogo      my @possdoms = &Apache::lonnet::current_machine_domains();
     </div>      if (grep(/^\Q$domain\E$/,@possdoms)) {
     <br style="clear:both;" />          $showadminmail=&Apache::loncommon::designparm('login.adminmail',$domain);
  </div>      }
       my $showcoursecat =
 <script type="text/javascript">          &Apache::loncommon::designparm('login.coursecatalog',$domain);
 // <![CDATA[      my $shownewuserlink =
 // the if prevents the script error if the browser can not handle this          &Apache::loncommon::designparm('login.newuser',$domain);
 if ( document.client.uname ) { document.client.uname.focus(); }      my $showhelpdesk =
 // ]]>          &Apache::loncommon::designparm('login.helpdesk',$domain);
 </script>      my $now=time;
 $helpdeskscript      my $js = (<<ENDSCRIPT);
   
 ENDDOCUMENT  <script type="text/javascript" language="JavaScript">
     my %endargs = ( 'noredirectlink' => 1, );  // <![CDATA[
     $r->print(&Apache::loncommon::end_page(\%endargs));  function send()
     return OK;  {
 }  this.document.server.elements.uname.value
   =this.document.client.elements.uname.value;
 sub check_loginvia {  
     my ($domain,$lonhost) = @_;  this.document.server.elements.udom.value
     if ($domain eq '' || $lonhost eq '') {  =this.document.client.elements.udom.value;
         return;  
     }  uextkey=this.document.client.elements.uextkey.value;
     my %domconfhash = &Apache::loncommon::get_domainconf($domain);  lextkey=this.document.client.elements.lextkey.value;
     my $loginvia = $domconfhash{$domain.'.login.loginvia_'.$lonhost};  initkeys();
     my $loginvia_exempt = $domconfhash{$domain.'.login.loginvia_exempt_'.$lonhost};  
     my $output;  if(this.document.server.action.substr(0,5) === 'http:'){
     if ($loginvia ne '') {      this.document.server.elements.upass0.value
         my $noredirect;          =getCrypted(this.document.client.elements.upass$now.value);
         my $ip = $ENV{'REMOTE_ADDR'};  } else {
         if ($ip eq '127.0.0.1') {      this.document.server.elements.upass0.value
             $noredirect = 1;          =this.document.client.elements.upass$now.value;
         } else {  }
             if ($loginvia_exempt ne '') {  
                 my @exempt = split(',',$loginvia_exempt);  this.document.client.elements.uname.value='';
                 if (grep(/^\Q$ip\E$/,@exempt)) {  this.document.client.elements.upass$now.value='';
                     $noredirect = 1;  
                 }  this.document.server.submit();
             }  return false;
         }  }
         unless ($noredirect) {  
             my ($newhost,$path);  function enableInput() {
             if ($loginvia =~ /:/) {      this.document.client.elements.upass$now.removeAttribute("readOnly");
                 ($newhost,$path) = split(':',$loginvia);      this.document.client.elements.uname.removeAttribute("readOnly");
             } else {      this.document.client.elements.udom.removeAttribute("readOnly");
                 $newhost = $loginvia;      return;
             }  }
             if ($newhost ne $lonhost) {  
                 if (&Apache::lonnet::hostname($newhost) ne '') {  // ]]>
                     $output = &redirect_page($newhost,$path);  </script>
                 }  
             }  ENDSCRIPT
         }  
     }      my ($lonhost_in_use,@hosts,%defaultdomconf,$saml_prefix,$saml_landing,
     return $output;          $samlssotext,$samlnonsso,$samlssoimg,$samlssoalt,$samlssourl,$samltooltip);
 }      %defaultdomconf = &Apache::loncommon::get_domainconf($defdom);
       @hosts = &Apache::lonnet::current_machine_ids();
 sub redirect_page {      $lonhost_in_use = $lonhost;
     my ($desthost,$path) = @_;      if (@hosts > 1) {
     my $protocol = $Apache::lonnet::protocol{$desthost};          foreach my $hostid (@hosts) {
     $protocol = 'http' if ($protocol ne 'https');              if (&Apache::lonnet::host_domain($hostid) eq $defdom) {
     unless ($path =~ m{^/}) {                  $lonhost_in_use = $hostid;
         $path = '/'.$path;                  last;
     }              }
     my $url = $protocol.'://'.&Apache::lonnet::hostname($desthost).$path;          }
     if ($env{'form.firsturl'} ne '') {      }
         $url .='?firsturl='.$env{'form.firsturl'};      $saml_prefix = $defdom.'.login.saml_';
     }      if ($defaultdomconf{$saml_prefix.$lonhost_in_use}) {
     my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,          $saml_landing = 1;
                                                     {'redirect' => [0,$url],});          $samlssotext = $defaultdomconf{$saml_prefix.'text_'.$lonhost_in_use};
     my $end_page   = &Apache::loncommon::end_page();          $samlnonsso = $defaultdomconf{$saml_prefix.'notsso_'.$lonhost_in_use};
     return $start_page.$end_page;          $samlssoimg = $defaultdomconf{$saml_prefix.'img_'.$lonhost_in_use};
 }          $samlssoalt = $defaultdomconf{$saml_prefix.'alt_'.$lonhost_in_use};
           $samlssourl = $defaultdomconf{$saml_prefix.'url_'.$lonhost_in_use};
 sub contactdisplay {          $samltooltip = $defaultdomconf{$saml_prefix.'title_'.$lonhost_in_use};
     my ($lt,$servadm,$showadminmail,$authdomain,$helpdeskscript,$showhelpdesk,      }
         $possdoms) = @_;      if ($saml_landing) {
     my $contactblock;         if ($samlssotext eq '') {
     my $origmail;             $samlssotext = 'SSO Login';
     if (ref($possdoms) eq 'ARRAY') {         }
         if (grep(/^\Q$authdomain\E$/,@{$possdoms})) {          if ($samlnonsso eq '') {
             $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};             $samlnonsso = 'Non-SSO Login';
         }         }
     }         $js .= <<"ENDSAMLJS";
     my $requestmail =   
         &Apache::loncommon::build_recipient_list(undef,'helpdeskmail',  <script type="text/javascript">
                                                  $authdomain,$origmail);  // <![CDATA[
     unless ($showhelpdesk eq '0') {  function toggleLClogin() {
         if ($requestmail =~ m/[^\@]+\@[^\@]+/) {      if (document.getElementById('LC_standard_login')) {
             $showhelpdesk = 1;          if (document.getElementById('LC_standard_login').style.display == 'none') {
         } else {              document.getElementById('LC_standard_login').style.display = 'inline-block';
             $showhelpdesk = 0;              if (document.getElementById('LC_login_text')) {
         }                  document.getElementById('LC_login_text').innerHTML = '$samlnonsso';
     }              }
     if ($servadm && $showadminmail) {              if ( document.client.uname ) { document.client.uname.focus(); }
         $contactblock .= $$lt{'servadm'}.':<br />'.              if (document.getElementById('LC_SSO_login')) {
                          '<tt>'.$servadm.'</tt><br />';                  document.getElementById('LC_SSO_login').style.display = 'none';
     }              }
     if ($showhelpdesk) {          } else {
         $contactblock .= '<a href="javascript:helpdesk()">'.$lt->{'helpdesk'}.'</a><br />';              document.getElementById('LC_standard_login').style.display = 'none';
         my $thisurl = &escape('/adm/login');              if (document.getElementById('LC_login_text')) {
         $$helpdeskscript = <<"ENDSCRIPT";                  document.getElementById('LC_login_text').innerHTML = '$samlssotext';
 <script type="text/javascript">              }
 // <![CDATA[              if (document.getElementById('LC_SSO_login')) {
 function helpdesk() {                  document.getElementById('LC_SSO_login').style.display = 'inline-block';
     var possdom = document.client.udom.value;              }
     var codedom = possdom.replace( new RegExp("[^A-Za-z0-9.\\-]","g"),'');          }
     if (codedom == '') {      }
         codedom = "$authdomain";      return;
     }  }
     var querystr = "origurl=$thisurl&codedom="+codedom;  
     document.location.href = "/adm/helpdesk?"+querystr;  // ]]>
     return;  </script>
 }  
 // ]]>  ENDSAMLJS
 </script>      }
 ENDSCRIPT  
     }  # --------------------------------------------------- Print login screen header
     return $contactblock;  
 }      my %add_entries = (
          bgcolor      => "$mainbg",
 sub forgotpwdisplay {         text         => "$font",
     my (%lt) = @_;         link         => "$link",
     my $prompt_for_resetpw = 1;          vlink        => "$vlink",
     if ($prompt_for_resetpw) {         alink        => "$alink",
         return '<a href="/adm/resetpw">'.$lt{'forgotpw'}.'</a>';                 onload       => 'javascript:enableInput();',);
     }  
     return;      my ($headextra,$headextra_exempt);
 }      $headextra = $defaultdomconf{$defdom.'.login.headtag_'.$lonhost_in_use};
       $headextra_exempt = $defaultdomconf{$domain.'.login.headtag_exempt_'.$lonhost_in_use};
 sub coursecatalog_link {      if ($headextra) {
     my ($linkname) = @_;          my $omitextra;
     return <<"END";          if ($headextra_exempt ne '') {
       <a href="/adm/coursecatalog">$linkname</a>              my @exempt = split(',',$headextra_exempt);
 END              my $ip = &Apache::lonnet::get_requestor_ip();
 }              if (grep(/^\Q$ip\E$/,@exempt)) {
                   $omitextra = 1;
 sub newuser_link {              }
     my ($linkname) = @_;          }
     return '<a href="/adm/createaccount">'.$linkname.'</a>';          unless ($omitextra) {
 }              my $confname = $defdom.'-domainconfig';
               if ($headextra =~ m{^\Q/res/$defdom/$confname/login/headtag/$lonhost_in_use/\E}) {
 1;                  my $extra = &Apache::lonnet::getfile(&Apache::lonnet::filelocation("",$headextra));
 __END__                  unless ($extra eq '-1') {
                       $js .= "\n".$extra."\n";
                   }
               }
           }
       }
   
       $r->print(&Apache::loncommon::start_page('The LearningOnline Network with CAPA Login',$js,
          { 'redirect'       => [$expire,'/adm/roles'],
    'add_entries' => \%add_entries,
    'only_body'   => 1,}));
   
   # ----------------------------------------------------------------------- Texts
   
       my %lt=&Apache::lonlocal::texthash(
             'un'       => 'Username',
             'pw'       => 'Password',
             'dom'      => 'Domain',
             'perc'     => 'percent',
             'load'     => 'Server Load',
             'userload' => 'User Load',
             'catalog'  => 'Course/Community Catalog',
             'log'      => 'Log in',
             'help'     => 'Log-in Help',
             'serv'     => 'Server',
             'servadm'  => 'Server Administration',
             'helpdesk' => 'Contact Helpdesk',
             'forgotpw' => 'Forgot password?',
             'newuser'  => 'New User?',
             'change'   => 'Change?',
          );
   # -------------------------------------------------- Change password field name
   
       my $forgotpw = &forgotpwdisplay(%lt);
       $forgotpw .= '<br />' if $forgotpw;
       my $loginhelp = &Apache::lonauth::loginhelpdisplay($authdomain);
       if ($loginhelp) {
           $loginhelp = '<a href="'.$loginhelp.'">'.$lt{'help'}.'</a><br />';
       }
   
   # ---------------------------------------------------- Serve out DES JavaScript
       {
       my $jsh=Apache::File->new($include."/londes.js");
       $r->print(<$jsh>);
       }
   # ---------------------------------------------------------- Serve rest of page
   
       $r->print(
       '<div class="LC_Box"'
      .' style="margin:0 auto; padding:10px; width:90%; height: auto; background-color:#FFFFFF;">'
   );
   
       $r->print(<<ENDSERVERFORM);
   <form name="server" action="/adm/authenticate" method="post" target="_top">
      <input type="hidden" name="logtoken" value="$logtoken" />
      <input type="hidden" name="serverid" value="$lonhost" />
      <input type="hidden" name="uname" value="" />
      <input type="hidden" name="upass0" value="" />
      <input type="hidden" name="udom" value="" />
      <input type="hidden" name="localpath" value="$env{'form.localpath'}" />
      <input type="hidden" name="localres" value="$env{'form.localres'}" />
     </form>
   ENDSERVERFORM
       my $coursecatalog;
       if (($showcoursecat eq '') || ($showcoursecat)) {
           $coursecatalog = &coursecatalog_link($lt{'catalog'}).'<br />';
       }
       my $newuserlink;
       if ($shownewuserlink) {
           $newuserlink = &newuser_link($lt{'newuser'}).'<br />';
       }
       my $logintitle =
           '<h2 class="LC_hcell"'
          .' style="background:'.$loginbox_header_bgcol.';'
          .' color:'.$loginbox_header_textcol.'">'
          .$lt{'log'}
          .'</h2>';
   
       my $noscript_warning='<noscript><span class="LC_warning"><b>'
                           .&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.')
                           .'</b></span></noscript>';
       my $helpdeskscript;
       my $contactblock = &contactdisplay(\%lt,$servadm,$showadminmail,
                                          $authdomain,\$helpdeskscript,
                                          $showhelpdesk,\@possdoms);
   
       my $mobileargs;
       if ($clientmobile) {
           $mobileargs = 'autocapitalize="off" autocorrect="off"';
       }
       my $loginform=(<<LFORM);
   <form name="client" action="" onsubmit="return(send())" id="lclogin">
     <input type="hidden" name="lextkey" value="$lextkey" />
     <input type="hidden" name="uextkey" value="$uextkey" />
     <b><label for="uname">$lt{'un'}</label>:</b><br />
     <input type="text" name="uname" id="uname" size="15" value="$authusername" readonly="readonly" $mobileargs /><br />
     <b><label for="upass$now">$lt{'pw'}</label>:</b><br />
     <input type="password" name="upass$now" id="upass$now" size="15" readonly="readonly" /><br />
     <b><label for="udom">$lt{'dom'}</label>:</b><br />
     <input type="text" name="udom" id="udom" size="15" value="$authdomain" readonly="readonly" $mobileargs /><br />
     <input type="submit" value="$lt{'log'}" />
   </form>
   LFORM
   
       if ($showbanner) {
           my $alttext = &Apache::loncommon::designparm('login.alttext_img',$domain);
           if ($alttext eq '') {
               $alttext = 'The Learning Online Network with CAPA';
           }
           $r->print(<<HEADER);
   <!-- The LON-CAPA Header -->
   <div style="background:$pgbg;margin:0;width:100%;">
     <img src="$img" border="0" alt="$alttext" class="LC_maxwidth" id="lcloginbanner" />
   </div>
   HEADER
       }
   
       my $stdauthformstyle = 'inline-block';
       my $ssoauthstyle = 'none';
       my $logintype;
       $r->print('<div style="float:left;margin-top:0;">');
       if ($saml_landing) {
           $ssoauthstyle = 'inline-block';
           $stdauthformstyle = 'none';
           $logintype = $samlssotext;
           my $ssologin = '/adm/sso';
           if ($samlssourl  ne '') {
               $ssologin = $samlssourl;
           }
           if (($logtoken eq 'con_lost') || ($logtoken eq 'no_such_host')) {
               my $querystring;
               if ($env{'form.firsturl'} ne '') {
                   $querystring = 'origurl=';
                   if ($env{'form.firsturl'} =~ /[^\x00-\xFF]/) {
                       $querystring .= &uri_escape_utf8($env{'form.firsturl'});
                   } else {
                       $querystring .= &uri_escape($env{'form.firsturl'});
                   }
                   $querystring = &HTML::Entities::encode($querystring,"'");
               }
               if ($env{'form.ltoken'} ne '') {
                   $querystring .= (($querystring eq '')?'':'&amp;') . 'ltoken='.
                                     &HTML::Entities::encode(&uri_escape($env{'form.ltoken'}));
               } elsif ($env{'form.linkkey'}) {
                   $querystring .= (($querystring eq '')?'':'&amp;') . 'linkkey='.
                                     &HTML::Entities::encode(&uri_escape($env{'form.linkkey'}));
               }
               if ($querystring ne '') {
                   $ssologin .= (($ssologin=~/\?/)?'&amp;':'?') . $querystring;
               }
           } elsif ($logtoken ne '') {
               $ssologin .= (($ssologin=~/\?/)?'&amp;':'?') . 'logtoken='.$logtoken;
           }
           my $ssohref;
           if ($samlssoimg ne '') {
               $ssohref = '<a href="'.$ssologin.'" title="'.$samltooltip.'">'.
                          '<img src="'.$samlssoimg.'" alt="'.$samlssoalt.'" id="lcssobutton" /></a>';
           } else {
               $ssohref = '<a href="'.$ssologin.'">'.$samlssotext.'</a>';
           }
           if (($env{'form.saml'} eq 'no') ||
               (($env{'form.username'} ne '') && ($env{'form.domain'} ne ''))) {
               $ssoauthstyle = 'none';
               $stdauthformstyle = 'inline-block';
               $logintype = $samlnonsso;
           }
           $r->print(<<ENDSAML);
   <p>
   Log-in type:
   <span style="font-weight:bold" id="LC_login_text">$logintype</span><br />
   <span><a href="javascript:toggleLClogin();" style="color:#000000">$lt{'change'}</a></span>
   </p>
   <div style="display:$ssoauthstyle" id="LC_SSO_login">
   <div class="LC_Box" style="padding-top: 10px;">
   $ssohref
   $noscript_warning
   </div>
   <div class="LC_Box" style="padding-top: 10px;">
   $loginhelp
   $contactblock
   $coursecatalog
   </div>
   </div>
   ENDSAML
       } else {
           if ($env{'form.ltoken'}) {
               &Apache::lonnet::tmpdel($env{'form.ltoken'});
               delete($env{'form.ltoken'});
           }
       }
       my $in_frame_js;
       if ($linkprot_for_login) {
           my ($linkprotector,$linkproturi) = split(/:/,$linkprot_for_login,2);
           if (($linkprotector =~ /^\d+(c|d)$/) && ($linkproturi =~ m{^/+tiny/+$LONCAPA::match_domain/+\w+$})) {
               my $set_target;
               if (($env{'form.retry'}) || ($env{'form.sso'})) {
                   if ($linkproturi eq $env{'form.firsturl'}) {
                       $set_target = "    document.server.target = '_self';";
                   }
               } else {
                   $set_target = <<ENDTARG;
       var linkproturi = '$linkproturi';
       var path = document.location.pathname.replace( new RegExp('^/adm/launch'),'');
       if (linkproturi == path) {
           document.server.target = '_self';
       }
   ENDTARG
               }
               $in_frame_js = <<ENDJS;
   <script type="text/javascript">
   // <![CDATA[
   if ((window.self !== window.top) && (document.server.target != '_self')) {
       $set_target
   }
   // ]]>
   </script>
   ENDJS
           }
       }
   
       $r->print(<<ENDLOGIN);
   <div style="display:$stdauthformstyle;" id="LC_standard_login">
   <div class="LC_Box" style="background:$loginbox_bg;">
     $logintitle
     $loginform
     $noscript_warning
   </div>
    
   <div class="LC_Box" style="padding-top: 10px;">
     $loginhelp
     $forgotpw
     $contactblock
     $newuserlink
     $coursecatalog
   </div>
   </div>
   
   ENDLOGIN
       $r->print('</div><div>'."\n");
       if ($showmainlogo) {
           my $alttext = &Apache::loncommon::designparm('login.alttext_logo',$domain);
           $r->print(' <img src="'.$logo.'" alt="'.$alttext.'" class="LC_maxwidth" id="lcloginmainlogo" />'."\n");
       }
   $r->print(<<ENDTOP);
   $announcements
   </div>
   <hr style="clear:both;" />
   ENDTOP
       my ($domainrow,$serverrow,$loadrow,$userloadrow,$versionrow);
       $domainrow = <<"END";
         <tr>
          <td  align="left" valign="top">
           <small><b>$lt{'dom'}:&nbsp;</b></small>
          </td>
          <td  align="left" valign="top">
           <small><tt>&nbsp;$domain</tt></small>
          </td>
         </tr>
   END
       $serverrow = <<"END";
         <tr>
          <td  align="left" valign="top">
           <small><b>$lt{'serv'}:&nbsp;</b></small>
          </td>
          <td align="left" valign="top">
           <small><tt>&nbsp;$lonhost ($role)</tt></small>
          </td>
         </tr>
   END
       if ($loadlim) {
           $loadrow = <<"END";
         <tr>
          <td align="left" valign="top">
           <small><b>$lt{'load'}:&nbsp;</b></small>
          </td>
          <td align="left" valign="top">
           <small><tt>&nbsp;$loadpercent $lt{'perc'}</tt></small>
          </td>
         </tr>
   END
       }
       if ($uloadlim) {
           $userloadrow = <<"END";
         <tr>
          <td align="left" valign="top">
           <small><b>$lt{'userload'}:&nbsp;</b></small>
          </td>
          <td align="left" valign="top">
           <small><tt>&nbsp;$userloadpercent $lt{'perc'}</tt></small>
          </td>
         </tr>
   END
       }
       if (($version ne '') && ($version ne '<!-- VERSION -->')) {
           $versionrow = <<"END";
         <tr>
          <td colspan="2" align="left">
           <small>$version</small>
          </td>
         </tr>
   END
       }
   
       $r->print(<<ENDDOCUMENT);
       <div style="float: left;">
        <table border="0" cellspacing="0" cellpadding="0">
   $domainrow
   $serverrow
   $loadrow    
   $userloadrow
   $versionrow
        </table>
       </div>
       <div style="float: right;">
       $domainlogo
       </div>
       <br style="clear:both;" />
    </div>
   
   $in_frame_js
   <script type="text/javascript">
   // <![CDATA[
   // the if prevents the script error if the browser can not handle this
   if ( document.client.uname ) { document.client.uname.focus(); }
   // ]]>
   </script>
   $helpdeskscript
   
   ENDDOCUMENT
       my %endargs = ( 'noredirectlink' => 1, );
       $r->print(&Apache::loncommon::end_page(\%endargs));
       return OK;
   }
   
   sub check_loginvia {
       my ($domain,$lonhost,$lonidsdir,$balcookie) = @_;
       if ($domain eq '' || $lonhost eq '' || $lonidsdir eq '') {
           return;
       }
       my %domconfhash = &Apache::loncommon::get_domainconf($domain);
       my $loginvia = $domconfhash{$domain.'.login.loginvia_'.$lonhost};
       my $loginvia_exempt = $domconfhash{$domain.'.login.loginvia_exempt_'.$lonhost};
       my $output;
       if ($loginvia ne '') {
           my $noredirect;
           my $ip = &Apache::lonnet::get_requestor_ip();  
           if ($ip eq '127.0.0.1') {
               $noredirect = 1;
           } else {
               if ($loginvia_exempt ne '') {
                   my @exempt = split(',',$loginvia_exempt);
                   if (grep(/^\Q$ip\E$/,@exempt)) {
                       $noredirect = 1;
                   }
               }
           }
           unless ($noredirect) {
               my ($newhost,$path);
               if ($loginvia =~ /:/) {
                   ($newhost,$path) = split(':',$loginvia);
               } else {
                   $newhost = $loginvia;
               }
               if ($newhost ne $lonhost) {
                   if (&Apache::lonnet::hostname($newhost) ne '') {
                       if ($balcookie) {
                           my ($balancer,$cookie) = split(/:/,$balcookie);
                           if ($cookie =~ /^($match_domain)_($match_username)_([a-f0-9]+)$/) {
                               my ($udom,$uname,$cookieid) = ($1,$2,$3);
                               unless (&Apache::lonnet::delbalcookie($cookie,$balancer) eq 'ok') {
                                   if ((-d $lonidsdir) && (opendir(my $dh,$lonidsdir))) {
                                       while (my $filename=readdir($dh)) {
                                           if ($filename=~/^(\Q$uname\E_\d+_\Q$udom\E_$match_lonid)\.id$/) {
                                               my $handle = $1;
                                               my %hash =
                                                   &Apache::lonnet::get_sessionfile_vars($handle,$lonidsdir,
                                                                                        ['request.balancercookie',
                                                                                         'user.linkedenv']);
                                               if ($hash{'request.balancercookie'} eq "$balancer:$cookieid") {
                                                   if (unlink("$lonidsdir/$filename")) {
                                                       if (($hash{'user.linkedenv'} =~ /^[a-f0-9]+_linked$/) &&
                                                           (-l "$lonidsdir/$hash{'user.linkedenv'}.id") &&
                                                           (readlink("$lonidsdir/$hash{'user.linkedenv'}.id") eq "$lonidsdir/$filename")) {
                                                           unlink("$lonidsdir/$hash{'user.linkedenv'}.id");
                                                       }
                                                   }
                                               }
                                               last;
                                           }
                                       }
                                       closedir($dh);
                                   }
                               }
                           }
                       }
                       $output = &redirect_page($newhost,$path);
                   }
               }
           }
       }
       return $output;
   }
   
   sub redirect_page {
       my ($desthost,$path) = @_;
       my $hostname = &Apache::lonnet::hostname($desthost);
       my $protocol = $Apache::lonnet::protocol{$desthost};
       $protocol = 'http' if ($protocol ne 'https');
       unless ($path =~ m{^/}) {
           $path = '/'.$path;
       }
       my $url = $protocol.'://'.$hostname.$path;
       my $args = {};
       if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
           $url = $protocol.'://'.$hostname.$env{'form.firsturl'};
           if (($env{'form.ltoken'}) || ($env{'form.linkprot'} ne '') ||
               ($env{'form.linkkey'} ne '')) {
               my %link_info;
               if ($env{'form.ltoken'}) {
                   %link_info = &Apache::lonnet::tmpget($env{'form.ltoken'});
                   &Apache::lonnet::tmpdel($env{'form.ltoken'});
                   $args->{'only_body'} = 1;
               } elsif ($env{'form.linkprot'}) {
                   $link_info{'linkprot'} = $env{'form.linkprot'};
                   foreach my $item ('linkprotuser','linkprotexit') {
                       if ($env{'form.'.$item}) {
                           $link_info{$item} = $env{'form.'.$item};
                       }
                   }
                   $args->{'only_body'} = 1;
               } elsif ($env{'form.linkkey'} ne '') {
                   $link_info{'linkkey'} = $env{'form.linkkey'};
               }
               my $token = &Apache::lonnet::tmpput(\%link_info,$desthost,'link');
               unless (($token eq 'con_lost') || ($token eq 'refused') ||
                       ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
                   $url .= '?ltoken='.$token;
               }
           }
       } else {
           my $querystring;
           if ($env{'form.firsturl'} ne '') {
               if ($env{'form.firsturl'} =~ /[^\x00-\xFF]/) {
                   $querystring = &uri_escape_utf8($env{'form.firsturl'});
               } else {
                   $querystring = &uri_escape($env{'form.firsturl'});
               }
               $querystring = &HTML::Entities::encode($querystring,"'");
               $querystring = '?firsturl='.$querystring;
           }
           if ($env{'form.ltoken'}) {
               my %link_info = &Apache::lonnet::tmpget($env{'form.ltoken'});
               &Apache::lonnet::tmpdel($env{'form.ltoken'});
               my $token = &Apache::lonnet::tmpput(\%link_info,$desthost,'link');
               unless (($token eq 'con_lost') || ($token eq 'refused') || ($token =~ /^error:/) ||
                       ($token eq 'unknown_cmd') || ($token eq 'no_such_host')) {
                   unless (($path eq '/adm/roles') || ($path eq '/adm/login')) {
                       $url = $protocol.'://'.$hostname.'/adm/roles';
                   }
                   $querystring .= (($querystring =~/^\?/)?'&amp;':'?') . 'ttoken='.$token;
               }
           }
           $url .= $querystring;
       }
       $args->{'redirect'} = [0,$url];
       my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,$args);
       my $end_page   = &Apache::loncommon::end_page();
       return $start_page.$end_page;
   }
   
   sub contactdisplay {
       my ($lt,$servadm,$showadminmail,$authdomain,$helpdeskscript,$showhelpdesk,
           $possdoms) = @_;
       my $contactblock;
       my $origmail;
       if (ref($possdoms) eq 'ARRAY') {
           if (grep(/^\Q$authdomain\E$/,@{$possdoms})) {
               $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};
           }
       }
       my $requestmail =
           &Apache::loncommon::build_recipient_list(undef,'helpdeskmail',
                                                    $authdomain,$origmail);
       unless ($showhelpdesk eq '0') {
           if ($requestmail =~ m/[^\@]+\@[^\@]+/) {
               $showhelpdesk = 1;
           } else {
               $showhelpdesk = 0;
           }
       }
       if ($servadm && $showadminmail) {
           $contactblock .= $$lt{'servadm'}.':<br />'.
                            '<tt>'.$servadm.'</tt><br />';
       }
       if ($showhelpdesk) {
           $contactblock .= '<a href="javascript:helpdesk()">'.$lt->{'helpdesk'}.'</a><br />';
           my $thisurl = &escape('/adm/login');
           $$helpdeskscript = <<"ENDSCRIPT";
   <script type="text/javascript">
   // <![CDATA[
   function helpdesk() {
       var possdom = document.client.udom.value;
       var codedom = possdom.replace( new RegExp("[^A-Za-z0-9.\\-]","g"),'');
       if (codedom == '') {
           codedom = "$authdomain";
       }
       var querystr = "origurl=$thisurl&codedom="+codedom;
       document.location.href = "/adm/helpdesk?"+querystr;
       return;
   }
   // ]]>
   </script>
   ENDSCRIPT
       }
       return $contactblock;
   }
   
   sub forgotpwdisplay {
       my (%lt) = @_;
       my $prompt_for_resetpw = 1;
       if ($prompt_for_resetpw) {
           return '<a href="/adm/resetpw">'.$lt{'forgotpw'}.'</a>';
       }
       return;
   }
   
   sub coursecatalog_link {
       my ($linkname) = @_;
       return <<"END";
         <a href="/adm/coursecatalog">$linkname</a>
   END
   }
   
   sub newuser_link {
       my ($linkname) = @_;
       return '<a href="/adm/createaccount">'.$linkname.'</a>';
   }
   
   sub decode_token {
       my ($info) = @_;
       my ($firsturl,@rest)=split(/\&/,$info);
       my %form;
       if ($firsturl ne '') {
           $form{'firsturl'} = &unescape($firsturl);
       }
       foreach my $item (@rest) {
           my ($key,$value) = split(/=/,$item);
           $form{$key} = &unescape($value);
       }
       return %form;
   }
   
   1;
   __END__

Removed from v.1.158.2.2  
changed lines
  Added in v.1.201


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
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.