Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.9 and 1.20

version 1.9, 2000/01/14 21:12:40 version 1.20, 2000/07/21 00:40:37
Line 1 Line 1
 # The LearningOnline Network  # The LearningOnline Network
 # TCP networking package  # TCP networking package
   #
   # Functions for use by content handlers:
   #
   # plaintext(short)   : plain text explanation of short term
   # allowed(short,url) : returns codes for allowed actions
   # appendenv(hash)    : adds hash to session environment
   # store(hash)        : stores hash permanently for this url
   # restore            : returns hash for this url
   # eget(namesp,array) : returns hash with keys from array filled in from namesp
   # get(namesp,array)  : returns hash with keys from array filled in from namesp
   # put(namesp,hash)   : stores hash in namesp
   # dump(namesp)       : dumps the complete namespace into a hash
   # ssi(url)           : does a complete request cycle on url to localhost
   # repcopy(filename)  : replicate file
   # dirlist(url)       : gets a directory listing
   #
 # 6/1/99,6/2,6/10,6/11,6/12,6/14,6/26,6/28,6/29,6/30,  # 6/1/99,6/2,6/10,6/11,6/12,6/14,6/26,6/28,6/29,6/30,
 # 7/1,7/2,7/9,7/10,7/12,7/14,7/15,7/19,  # 7/1,7/2,7/9,7/10,7/12,7/14,7/15,7/19,
 # 11/8,11/16,11/18,11/22,11/23,12/22,  # 11/8,11/16,11/18,11/22,11/23,12/22,
 # 01/06,01/13 Gerd Kortemeyer  # 01/06,01/13,02/24,02/28,02/29,
   # 03/01,03/02,03/06,03/07,03/13,
   # 04/05,05/29,05/31,06/01,
   # 06/05,06/26 Gerd Kortemeyer
   # 06/26 Ben Tyszka
   # 06/30,07/15,07/17,07/18 Gerd Kortemeyer
   
 package Apache::lonnet;  package Apache::lonnet;
   
 use strict;  use strict;
 use Apache::File;  use Apache::File;
 use LWP::UserAgent();  use LWP::UserAgent();
 use vars qw(%perlvar %hostname %homecache %spareid %hostdom %libserv $readit);  use HTTP::Headers;
   use vars 
   qw(%perlvar %hostname %homecache %spareid %hostdom %libserv %pr %prp $readit);
 use IO::Socket;  use IO::Socket;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
   
Line 55  sub reply { Line 78  sub reply {
     my ($cmd,$server)=@_;      my ($cmd,$server)=@_;
     my $answer=subreply($cmd,$server);      my $answer=subreply($cmd,$server);
     if ($answer eq 'con_lost') { $answer=subreply($cmd,$server); }      if ($answer eq 'con_lost') { $answer=subreply($cmd,$server); }
       if (($answer=~/^error:/) || ($answer=~/^refused/) || 
           ($answer=~/^rejected/)) {
          &logthis("<font color=blue>WARNING:".
                   " $cmd to $server returned $answer</font>");
       }
     return $answer;      return $answer;
 }  }
   
Line 75  sub reconlonc { Line 103  sub reconlonc {
             &logthis("$peerfile still not there, give it another try");              &logthis("$peerfile still not there, give it another try");
             sleep 5;              sleep 5;
             if (-e "$peerfile") { return; }              if (-e "$peerfile") { return; }
             &logthis("$peerfile still not there, giving up");              &logthis(
     "<font color=blue>WARNING: $peerfile still not there, giving up</font>");
         } else {          } else {
     &logthis("lonc at pid $loncpid not responding, giving up");      &logthis(
                  "<font color=blue>WARNING:".
                  " lonc at pid $loncpid not responding, giving up</font>");
         }          }
     } else {      } else {
         &logthis('lonc not running, giving up');       &logthis('<font color=blue>WARNING: lonc not running, giving up</font>');
     }      }
 }  }
   
 # ------------------------------------------------------ Critical communication  # ------------------------------------------------------ Critical communication
   
 sub critical {  sub critical {
     my ($cmd,$server)=@_;      my ($cmd,$server)=@_;
     my $answer=reply($cmd,$server);      my $answer=reply($cmd,$server);
Line 117  sub critical { Line 149  sub critical {
             }              }
             chomp($wcmd);              chomp($wcmd);
             if ($wcmd eq $cmd) {              if ($wcmd eq $cmd) {
  &logthis("Connection buffer $dfilename: $cmd");   &logthis("<font color=blue>WARNING: ".
                            "Connection buffer $dfilename: $cmd</font>");
                 &logperm("D:$server:$cmd");                  &logperm("D:$server:$cmd");
         return 'con_delayed';          return 'con_delayed';
             } else {              } else {
                 &logthis("CRITICAL CONNECTION FAILED: $server $cmd");                  &logthis("<font color=red>CRITICAL:"
                           ." Critical connection failed: $server $cmd</font>");
                 &logperm("F:$server:$cmd");                  &logperm("F:$server:$cmd");
                 return 'con_failed';                  return 'con_failed';
             }              }
Line 163  sub appenv { Line 197  sub appenv {
 }  }
   
 # ------------------------------ Find server with least workload from spare.tab  # ------------------------------ Find server with least workload from spare.tab
   
 sub spareserver {  sub spareserver {
     my $tryserver;      my $tryserver;
     my $spareserver='';      my $spareserver='';
Line 178  sub spareserver { Line 213  sub spareserver {
 }  }
   
 # --------- Try to authenticate user from domain's lib servers (first this one)  # --------- Try to authenticate user from domain's lib servers (first this one)
   
 sub authenticate {  sub authenticate {
     my ($uname,$upass,$udom)=@_;      my ($uname,$upass,$udom)=@_;
       $upass=escape($upass);
     if (($perlvar{'lonRole'} eq 'library') &&       if (($perlvar{'lonRole'} eq 'library') && 
         ($udom eq $perlvar{'lonDefDomain'})) {          ($udom eq $perlvar{'lonDefDomain'})) {
     my $answer=reply("encrypt:auth:$udom:$uname:$upass",$perlvar{'lonHostID'});      my $answer=reply("encrypt:auth:$udom:$uname:$upass",$perlvar{'lonHostID'});
Line 199  sub authenticate { Line 235  sub authenticate {
     my $tryserver;      my $tryserver;
     foreach $tryserver (keys %libserv) {      foreach $tryserver (keys %libserv) {
  if ($hostdom{$tryserver} eq $udom) {   if ($hostdom{$tryserver} eq $udom) {
            my $answer=reply("enc:auth:$udom:$uname:$upass",$tryserver);             my $answer=reply("encrypt:auth:$udom:$uname:$upass",$tryserver);
            if ($answer =~ /authorized/) {             if ($answer =~ /authorized/) {
               if ($answer eq 'authorized') {                if ($answer eq 'authorized') {
                  &logthis("User $uname at $udom authorized by $tryserver");                    &logthis("User $uname at $udom authorized by $tryserver"); 
Line 217  sub authenticate { Line 253  sub authenticate {
 }  }
   
 # ---------------------- Find the homebase for a user from domain's lib servers  # ---------------------- Find the homebase for a user from domain's lib servers
   
 sub homeserver {  sub homeserver {
     my ($uname,$udom)=@_;      my ($uname,$udom)=@_;
   
Line 237  sub homeserver { Line 274  sub homeserver {
 }  }
   
 # ----------------------------- Subscribe to a resource, return URL if possible  # ----------------------------- Subscribe to a resource, return URL if possible
   
 sub subscribe {  sub subscribe {
     my $fname=shift;      my $fname=shift;
     my $author=$fname;      my $author=$fname;
Line 255  sub subscribe { Line 293  sub subscribe {
 sub repcopy {  sub repcopy {
     my $filename=shift;      my $filename=shift;
     my $transname="$filename.in.transfer";      my $transname="$filename.in.transfer";
       if ((-e $filename) || (-e $transname)) { return OK; }
     my $remoteurl=subscribe($filename);      my $remoteurl=subscribe($filename);
     if ($remoteurl eq 'con_lost') {      if ($remoteurl eq 'con_lost') {
    &logthis("Subscribe returned con_lost: $filename");     &logthis("Subscribe returned con_lost: $filename");
Line 262  sub repcopy { Line 301  sub repcopy {
     } elsif ($remoteurl eq 'not_found') {      } elsif ($remoteurl eq 'not_found') {
    &logthis("Subscribe returned not_found: $filename");     &logthis("Subscribe returned not_found: $filename");
    return HTTP_NOT_FOUND;     return HTTP_NOT_FOUND;
     } elsif ($remoteurl eq 'forbidden') {      } elsif ($remoteurl eq 'rejected') {
    &logthis("Subscribe returned forbidden: $filename");     &logthis("Subscribe returned rejected: $filename");
            return FORBIDDEN;             return FORBIDDEN;
       } elsif ($remoteurl eq 'directory') {
              return OK;
     } else {      } else {
            my @parts=split(/\//,$filename);             my @parts=split(/\//,$filename);
            my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]";             my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]";
Line 285  sub repcopy { Line 326  sub repcopy {
            if ($response->is_error()) {             if ($response->is_error()) {
        unlink($transname);         unlink($transname);
                my $message=$response->status_line;                 my $message=$response->status_line;
                &logthis("LWP GET: $message: $filename");                 &logthis("<font color=blue>WARNING:"
                          ." LWP get: $message: $filename</font>");
                return HTTP_SERVICE_UNAVAILABLE;                 return HTTP_SERVICE_UNAVAILABLE;
            } else {             } else {
          if ($remoteurl!~/\.meta$/) {
                     my $mrequest=new HTTP::Request('GET',$remoteurl.'.meta');
                     my $mresponse=$ua->request($mrequest,$filename.'.meta');
                     if ($mresponse->is_error()) {
         unlink($filename.'.meta');
                         &logthis(
                        "<font color=yellow>INFO: No metadata: $filename</font>");
                     }
          }
                rename($transname,$filename);                 rename($transname,$filename);
                return OK;                 return OK;
            }             }
     }      }
 }  }
   
   # --------------------------------------------------------- Server Side Include
   
   sub ssi {
   
       my $fn=shift;
   
       my $ua=new LWP::UserAgent;
       my $request=new HTTP::Request('GET',"http://".$ENV{'HTTP_HOST'}.$fn);
       $request->header(Cookie => $ENV{'HTTP_COOKIE'});
       my $response=$ua->request($request);
   
       return $response->content;
   }
   
   # ------------------------------------------------------------------------- Log
   
   sub log {
       my ($dom,$nam,$hom,$what)=@_;
       return reply("log:$dom:$nam:$what",$hom);
   }
   
 # ----------------------------------------------------------------------- Store  # ----------------------------------------------------------------------- Store
   
 sub store {  sub store {
     my %storehash=shift;      my %storehash=shift;
     my $command="store:$ENV{'user.domain'}:$ENV{'user.name'}:"      my $namevalue='';
                ."$ENV{'user.class'}:$ENV{'request.filename'}:";      map {
           $namevalue.=escape($_).'='.escape($storehash{$_}).'&';
       } keys %storehash;
       $namevalue=~s/\&$//;
       return reply("store:$ENV{'user.domain'}:$ENV{'user.name'}:"
                  ."$ENV{'user.class'}:$ENV{'request.filename'}:$namevalue",
    "$ENV{'user.home'}");
 }  }
   
 # --------------------------------------------------------------------- Restore  # --------------------------------------------------------------------- Restore
   
 sub restore {  sub restore {
     my $command="restore:$ENV{'user.domain'}:$ENV{'user.name'}:"      my $answer=reply("restore:$ENV{'user.domain'}:$ENV{'user.name'}:"
                ."$ENV{'user.class'}:$ENV{'request.filename'}:";                 ."$ENV{'user.class'}:$ENV{'request.filename'}",
                   "$ENV{'user.home'}");
       my %returnhash=();
       map {
    my ($name,$value)=split(/\=/,$_);
           $returnhash{&unescape($name)}=&unescape($value);
       } split(/\&/,$answer);
       return %returnhash;
   }
   
   # -------------------------------------------------------- Get user priviledges
   
   sub rolesinit {
       my ($domain,$username,$authhost)=@_;
       my $rolesdump=reply("dump:$domain:$username:roles",$authhost);
       if (($rolesdump eq 'con_lost') || ($rolesdump eq '')) { return ''; }
       my %allroles=();
       my %thesepriv=();
       my $userroles='';
       my $now=time;
       my $thesestr;
   
       if ($rolesdump ne '') {
           map {
     if ($_!~/rolesdef\&/) {
               my ($area,$role)=split(/=/,$_);
               my ($trole,$tend,$tstart)=split(/_/,$role);
               if ($tend!=0) {
           if ($tend<$now) {
               $trole='';
                   } 
               }
               if ($tstart!=0) {
                   if ($tstart>$now) {
                      $trole='';        
                   }
               }
               if (($area ne '') && ($trole ne '')) {
                  $userroles.='user.role.'.$trole.'.'.$area.'='.
                              $tstart.'.'.$tend."\n";
                  my ($tdummy,$tdomain,$trest)=split(/\//,$area);
                  if ($trole =~ /^cr\//) {
      my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$trole);
                      my $homsvr=homeserver($rauthor,$rdomain);
                      if ($hostname{$homsvr} ne '') {
                         my $roledef=
     reply("get:$rdomain:$rauthor:roles:rolesdef&$rrole",
                                   $homsvr);
                         if (($roledef ne 'con_lost') && ($roledef ne '')) {
                            my ($syspriv,$dompriv,$coursepriv)=
        split(/&&/,$roledef);
                     $allroles{'/'}.=':'.$syspriv;
                            if ($tdomain ne '') {
                                $allroles{'/'.$tdomain.'/'}.=':'.$dompriv;
                                if ($trest ne '') {
                   $allroles{$area}.=':'.$coursepriv;
                                }
                    }
                         }
                      }
                  } else {
              $allroles{'/'}.=':'.$pr{$trole.':s'};
                      if ($tdomain ne '') {
                         $allroles{'/'.$tdomain.'/'}.=':'.$pr{$trole.':d'};
                         if ($trest ne '') {
             $allroles{$area}.=':'.$pr{$trole.':c'};
                         }
              }
          }
               }
             } 
           } split(/&/,$rolesdump);
           map {
               %thesepriv=();
               map {
                   if ($_ ne '') {
       my ($priviledge,$restrictions)=split(/&/,$_);
                       if ($restrictions eq '') {
    $thesepriv{$priviledge}='F';
                       } else {
                           if ($thesepriv{$priviledge} ne 'F') {
       $thesepriv{$priviledge}.=$restrictions;
                           }
                       }
                   }
               } split(/:/,$allroles{$_});
               $thesestr='';
               map { $thesestr.=':'.$_.'&'.$thesepriv{$_}; } keys %thesepriv;
               $userroles.='user.priv.'.$_.'='.$thesestr."\n";
           } keys %allroles;            
       }
       return $userroles;  
   }
   
   # --------------------------------------------------------------- get interface
   
   sub get {
      my ($namespace,@storearr)=@_;
      my $items='';
      map {
          $items.=escape($_).'&';
      } @storearr;
      $items=~s/\&$//;
    my $rep=reply("get:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
                    $ENV{'user.home'});
      my @pairs=split(/\&/,$rep);
      my %returnhash=();
      map {
         my ($key,$value)=split(/=/,$_);
         $returnhash{unespace($key)}=unescape($value);
      } @pairs;
      return %returnhash;
   }
   
   # -------------------------------------------------------------- dump interface
   
   sub dump {
      my $namespace=shift;
      my $rep=reply("dump:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace",
                   $ENV{'user.home'});
      my @pairs=split(/\&/,$rep);
      my %returnhash=();
      map {
         my ($key,$value)=split(/=/,$_);
         $returnhash{unespace($key)}=unescape($value);
      } @pairs;
      return %returnhash;
   }
   
   # --------------------------------------------------------------- put interface
   
   sub put {
      my ($namespace,%storehash)=@_;
      my $items='';
      map {
          $items.=escape($_).'='.escape($storehash{$_}).'&';
      } keys %storehash;
      $items=~s/\&$//;
      return reply("put:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
                    $ENV{'user.home'});
   }
   
   # -------------------------------------------------------------- eget interface
   
   sub eget {
      my ($namespace,@storearr)=@_;
      my $items='';
      map {
          $items.=escape($_).'&';
      } @storearr;
      $items=~s/\&$//;
    my $rep=reply("eget:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
                    $ENV{'user.home'});
      my @pairs=split(/\&/,$rep);
      my %returnhash=();
      map {
         my ($key,$value)=split(/=/,$_);
         $returnhash{unespace($key)}=unescape($value);
      } @pairs;
      return %returnhash;
   }
   
   # ------------------------------------------------- Check for a user priviledge
   
   sub allowed {
       my ($priv,$uri)=@_;
       $uri=~s/^\/res//;
       $uri=~s/^\///;
       if ($uri=~/^adm\//) {
    return 'F';
       }
       my $thisallowed='';
       if ($ENV{'user.priv./'}=~/$priv\&([^\:]*)/) {
          $thisallowed.=$1;
       }
       if ($ENV{'user.priv./'.(split(/\//,$uri))[0].'/'}=~/$priv\&([^\:]*)/) {
          $thisallowed.=$1;
       }
       if ($ENV{'user.priv./'.$uri}=~/$priv\&([^\:]*)/) {
          $thisallowed.=$1;
       }
       return $thisallowed;
   }
   
   # ----------------------------------------------------------------- Define Role
   
   sub definerole {
     if (allowed('mcr','/')) {
       my ($rolename,$sysrole,$domrole,$courole)=@_;
       my $command="encrypt:rolesput:$ENV{'user.domain'}:$ENV{'user.name'}:".
                   "$ENV{'user.domain'}:$ENV{'user.name'}:".
           "rolesdef&$rolename=$sysrole&&$domrole&&$courole";
       return reply($command,$ENV{'user.home'});
     } else {
       return 'refused';
     }
   }
   
   # ------------------------------------------------------------------ Plain Text
   
   sub plaintext {
       return $prp{$_};
   }
   
   # ----------------------------------------------------------------- Assign Role
   
   sub assignrole {
   }
   
   # ------------------------------------------------------------ Directory lister
   
   sub dirlist {
       my $uri=shift;
       $uri=~s/^\///;
       $uri=~s/\/$//;
       my ($res,$udom,$uname,@rest)=split(/\//,$uri);
       if ($udom) {
        if ($uname) {
          my $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/'.$uri,
                         homeserver($uname,$udom));
          return split(/:/,$listing);
        } else {
          my $tryserver;
          my %allusers=();
          foreach $tryserver (keys %libserv) {
     if ($hostdom{$tryserver} eq $udom) {
                my $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'.$udom,
          $tryserver);
                if (($listing ne 'no_such_dir') && ($listing ne 'empty')
                 && ($listing ne 'con_lost')) {
                   map {
                     my ($entry,@stat)=split(/&/,$_);
                     $allusers{$entry}=1;
                   } split(/:/,$listing);
                }
     }
          }
          my $alluserstr='';
          map {
              $alluserstr.=$_.'&user:';
          } sort keys %allusers;
          $alluserstr=~s/:$//;
          return split(/:/,$alluserstr);
        } 
      } else {
          my $tryserver;
          my %alldom=();
          foreach $tryserver (keys %libserv) {
      $alldom{$hostdom{$tryserver}}=1;
          }
          my $alldomstr='';
          map {
             $alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$_.'&domain:';
          } sort keys %alldom;
          $alldomstr=~s/:$//;
          return split(/:/,$alldomstr);       
      }
   }
   
   # -------------------------------------------------------- Escape Special Chars
   
   sub escape {
       my $str=shift;
       $str =~ s/(\W)/"%".unpack('H2',$1)/eg;
       return $str;
   }
   
   # ----------------------------------------------------- Un-Escape Special Chars
   
   sub unescape {
       my $str=shift;
       $str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
       return $str;
 }  }
   
 # ================================================================ Main Program  # ================================================================ Main Program
Line 349  if ($readit ne 'done') { Line 699  if ($readit ne 'done') {
        }         }
     }      }
 }  }
   # ------------------------------------------------------------ Read permissions
   {
       my $config=Apache::File->new("$perlvar{'lonTabDir'}/roles.tab");
   
       while (my $configline=<$config>) {
          chomp($configline);
          my ($role,$perm)=split(/ /,$configline);
          if ($perm ne '') { $pr{$role}=$perm; }
       }
   }
   
   # -------------------------------------------- Read plain texts for permissions
   {
       my $config=Apache::File->new("$perlvar{'lonTabDir'}/rolesplain.tab");
   
       while (my $configline=<$config>) {
          chomp($configline);
          my ($short,$plain)=split(/:/,$configline);
          if ($plain ne '') { $prp{$short}=$plain; }
       }
   }
   
 $readit='done';  $readit='done';
 &logthis('Read configuration');  &logthis('<font color=yellow>INFO: Read configuration</font>');
 }  }
 }  }
 1;  1;
   
   
   
   

Removed from v.1.9  
changed lines
  Added in v.1.20


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>