--- loncom/lonnet/perl/lonnet.pm 2001/08/07 14:33:53 1.141 +++ loncom/lonnet/perl/lonnet.pm 2001/08/23 22:44:51 1.156 @@ -72,7 +72,12 @@ # EXT(name) : value of a variable # symblist(map,hash) : Updates symbolic storage links # symbread([filename]) : returns the data handle (filename optional) -# rndseed() : returns a random seed +# rndseed([symb,courseid,domain,uname]) +# : returns a random seed, all arguments are optional, +# if they aren't sent it use the environment to derive +# them +# Note: if symb isn't sent and it can't get one from +# &symbread it will use the current time as it's return # receipt() : returns a receipt to be given out to users # getfile(filename) : returns the contents of filename, or a -1 if it can't # be found, replicates and subscribes to the file @@ -122,7 +127,7 @@ # 5/30 H. K. Ng # 6/1 Gerd Kortemeyer # July Guy Albertelli -# 8/4,8/7 Gerd Kortemeyer +# 8/4,8/7,8/8,8/9,8/11,8/16,8/17,8/18,8/20,8/23 Gerd Kortemeyer package Apache::lonnet; @@ -131,7 +136,7 @@ use Apache::File; use LWP::UserAgent(); use HTTP::Headers; use vars -qw(%perlvar %hostname %homecache %spareid %hostdom %libserv %pr %prp %fe %fd $readit %metacache %packagetab); +qw(%perlvar %hostname %homecache %hostip %spareid %hostdom %libserv %pr %prp %fe %fd $readit %metacache %packagetab); use IO::Socket; use GDBM_File; use Apache::Constants qw(:common :http); @@ -276,7 +281,8 @@ sub appenv { map { if (($newenv{$_}=~/^user\.role/) || ($newenv{$_}=~/^user\.priv/)) { &logthis("WARNING: ". - "Attempt to modify environment ".$_." to ".$newenv{$_}); + "Attempt to modify environment ".$_." to ".$newenv{$_} + .''); delete($newenv{$_}); } else { $ENV{$_}=$newenv{$_}; @@ -659,6 +665,92 @@ sub log { return critical("log:$dom:$nam:$what",$hom); } +# ----------------------------------------------------------- Check out an item + +sub checkout { + my ($symb,$tuname,$tudom,$tcrsid)=@_; + my $now=time; + my $lonhost=$perlvar{'lonHostID'}; + my $infostr=&escape( + $tuname.'&'. + $tudom.'&'. + $tcrsid.'&'. + $symb.'&'. + $now.'&'.$ENV{'REMOTE_ADDR'}); + my $token=&reply('tmpput:'.$infostr,$lonhost); + if ($token=~/^error\:/) { + &logthis("WARNING: ". + "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb. + ""); + return ''; + } + + $token=~s/^(\d+)\_.*\_(\d+)$/$1\*$2\*$lonhost/; + $token=~tr/a-z/A-Z/; + + my %infohash=('resource.0.outtoken' => $token, + 'resource.0.checkouttime' => $now, + 'resource.0.outremote' => $ENV{'REMOTE_ADDR'}); + + unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { + return ''; + } else { + &logthis("WARNING: ". + "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb. + ""); + } + + if (&log($tudom,$tuname,&homeserver($tuname,$tudom), + &escape('Checkout '.$infostr.' - '. + $token)) ne 'ok') { + return ''; + } else { + &logthis("WARNING: ". + "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb. + ""); + } + return $token; +} + +# ------------------------------------------------------------ Check in an item + +sub checkin { + my $token=shift; + my $now=time; + my ($ta,$tb,$lonhost)=split(/\*/,$token); + $lonhost=~tr/A-Z/a-z/; + my $dtoken=$ta.'_'.$hostip{$lonhost}.'_'.$tb; + $dtoken=~s/\W/\_/g; + my ($tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)= + split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost))); + + unless (($tuname) && ($tudom)) { + &logthis('Check in '.$token.' ('.$dtoken.') failed'); + return ''; + } + + unless (&allowed('mgr',$tcrsid)) { + &logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '. + $ENV{'user.name'}.' - '.$ENV{'user.domain'}); + return ''; + } + + my %infohash=('resource.0.intoken' => $token, + 'resource.0.checkintime' => $now, + 'resource.0.inremote' => $ENV{'REMOTE_ADDR'}); + + unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { + return ''; + } + + if (&log($tudom,$tuname,&homeserver($tuname,$tudom), + &escape('Checkin - '.$token)) ne 'ok') { + return ''; + } + + return ($symb,$tuname,$tudom,$tcrsid); +} + # --------------------------------------------- Set Expire Date for Spreadsheet sub expirespread { @@ -896,7 +988,7 @@ sub rolesinit { my $author=0; map { %thesepriv=(); - if (($_!~/^st/) && ($_!~/^ta/)) { $adv=1; } + if (($_!~/^st/) && ($_!~/^ta/) && ($_!~/^cm/)) { $adv=1; } if (($_=~/^au/) || ($_=~/^ca/)) { $author=1; } map { if ($_ ne '') { @@ -1035,6 +1127,8 @@ sub eget { sub allowed { my ($priv,$uri)=@_; + + my $orguri=$uri; $uri=&declutter($uri); # Free bre access to adm and meta resources @@ -1108,16 +1202,28 @@ sub allowed { } } - if (($ENV{'HTTP_REFERER'}) && ($checkreferer)) { - my $refuri=$ENV{'HTTP_REFERER'}; - $refuri=~s/^http\:\/\/$ENV{'request.host'}//i; - $refuri=&declutter($refuri); + if ($checkreferer) { + my $refuri=$ENV{'httpref.'.$orguri}; + + unless ($refuri) { + map { + if ($_=~/^httpref\..*\*/) { + my $pattern=$_; + $pattern=~s/^httpref\.\/res\///; + $pattern=~s/\*/\[\^\/\]\+/g; + $pattern=~s/\//\\\//g; + if ($orguri=~/$pattern/) { + $refuri=$ENV{$_}; + } + } + } keys %ENV; + } + if ($refuri) { + $refuri=&declutter($refuri); my @uriparts=split(/\//,$refuri); my $filename=$uriparts[$#uriparts]; my $pathname=$refuri; $pathname=~s/\/$filename$//; - my @filenameparts=split(/\./,$uri); - if (&fileembstyle($filenameparts[$#filenameparts]) ne 'ssi') { if ($ENV{'acc.res.'.$ENV{'request.course.id'}.'.'.$pathname}=~ /\&$filename\:([\d\|]+)\&/) { my $refstatecond=$1; @@ -1127,8 +1233,8 @@ sub allowed { $uri=$refuri; $statecond=$refstatecond; } - } } + } } } @@ -1674,7 +1780,7 @@ sub condval { # --------------------------------------------------------- Value of a Variable sub EXT { - my $varname=shift; + my ($varname,$symbparm)=@_; unless ($varname) { return ''; } my ($realm,$space,$qualifier,@therest)=split(/\./,$varname); my $rest; @@ -1735,8 +1841,17 @@ sub EXT { $spacequalifierrest}; } elsif ($realm eq 'resource') { if ($ENV{'request.course.id'}) { + +# print '
'.$space.' - '.$qualifier.' - '.$spacequalifierrest; + + # ----------------------------------------------------- Cascading lookup scheme - my $symbp=&symbread(); + my $symbp; + if ($symbparm) { + $symbp=$symbparm; + } else { + $symbp=&symbread(); + } my $mapp=(split(/\_\_\_/,$symbp))[0]; my $symbparm=$symbp.'.'.$spacequalifierrest; @@ -1824,6 +1939,21 @@ sub EXT { 'parameter_'.$spacequalifierrest); if ($metadata) { return $metadata; } +# ------------------------------------------------------------------ Cascade up + + unless ($space eq '0') { + my ($part,$id)=split(/\_/,$space); + if ($id) { + my $partgeneral=&EXT('resource.'.$part.'.'.$qualifierrest, + $symbparm); + if ($partgeneral) { return $partgeneral; } + } else { + my $resourcegeneral=&EXT('resource.0.'.$qualifierrest, + $symbparm); + if ($resourcegeneral) { return $resourcegeneral; } + } + } + # ---------------------------------------------------- Any other user namespace } elsif ($realm eq 'environment') { # ----------------------------------------------------------------- environment @@ -1872,13 +2002,14 @@ sub metadata { if ($_=~/^$package\&/) { my ($pack,$name,$subp)=split(/\&/,$_); my $value=$packagetab{$_}; + my $part=$keyroot; + $part=~s/^\_//; if ($subp eq 'display') { - my $part=$keyroot; - $part=~s/^\_//; $value.=' [Part: '.$part.']'; } my $unikey='parameter'.$keyroot.'_'.$name; $metathesekeys{$unikey}=1; + $metacache{$uri.':'.$unikey.'.part'}=$part; unless (defined($metacache{$uri.':'.$unikey.'.'.$subp})) { $metacache{$uri.':'.$unikey.'.'.$subp}=$value; @@ -2019,16 +2150,21 @@ sub numval { } sub rndseed { - my $symb; - unless ($symb=&symbread()) { return time; } - { + my ($symb,$courseid,$domain,$username)=@_; + if (!$symb) { + unless ($symb=&symbread()) { return time; } + } + if (!$courseid) { $courseid=$ENV{'request.course.id'};} + if (!$domain) {$domain=$ENV{'user.domain'};} + if (!$username) {$username=$ENV{'user.name'};} + { use integer; my $symbchck=unpack("%32C*",$symb) << 27; my $symbseed=numval($symb) << 22; - my $namechck=unpack("%32C*",$ENV{'user.name'}) << 17; - my $nameseed=numval($ENV{'user.name'}) << 12; - my $domainseed=unpack("%32C*",$ENV{'user.domain'}) << 7; - my $courseseed=unpack("%32C*",$ENV{'request.course.id'}); + my $namechck=unpack("%32C*",$username) << 17; + my $nameseed=numval($username) << 12; + my $domainseed=unpack("%32C*",$domain) << 7; + my $courseseed=unpack("%32C*",$courseid); my $num=$symbseed+$nameseed+$domainseed+$courseseed+$namechck+$symbchck; #uncommenting these lines can break things! #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck"); @@ -2150,9 +2286,11 @@ if ($readit ne 'done') { my $config=Apache::File->new("$perlvar{'lonTabDir'}/hosts.tab"); while (my $configline=<$config>) { + chomp($configline); my ($id,$domain,$role,$name,$ip)=split(/:/,$configline); $hostname{$id}=$name; $hostdom{$id}=$domain; + $hostip{$id}=$ip; if ($role eq 'library') { $libserv{$id}=$name; } } } @@ -2197,7 +2335,11 @@ if ($readit ne 'done') { while (my $configline=<$config>) { chomp($configline); my ($short,$plain)=split(/:/,$configline); - if ($plain ne '') { $packagetab{$short}=$plain; } + my ($pack,$name)=split(/\&/,$short); + if ($plain ne '') { + $packagetab{$pack.'&'.$name.'&name'}=$name; + $packagetab{$short}=$plain; + } } }