--- loncom/lonnet/perl/lonnet.pm 2001/08/18 14:17:50 1.152 +++ loncom/lonnet/perl/lonnet.pm 2001/10/06 20:57:45 1.162 @@ -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 @@ -113,6 +118,7 @@ # 05/01,06/01,09/01 Gerd Kortemeyer # 09/01 Guy Albertelli # 09/01,10/01,11/01 Gerd Kortemeyer +# YEAR=2001 # 02/27/01 Scott Harrison # 3/2 Gerd Kortemeyer # 3/15,3/19 Scott Harrison @@ -122,7 +128,9 @@ # 5/30 H. K. Ng # 6/1 Gerd Kortemeyer # July Guy Albertelli -# 8/4,8/7,8/8,8/9,8/11,8/16,8/17,8/18 Gerd Kortemeyer +# 8/4,8/7,8/8,8/9,8/11,8/16,8/17,8/18,8/20,8/23,9/20,9/21,9/26, +# 10/2 Gerd Kortemeyer +# 10/5 Scott Harrison package Apache::lonnet; @@ -131,7 +139,7 @@ use Apache::File; use LWP::UserAgent(); use HTTP::Headers; use vars -qw(%perlvar %hostname %homecache %hostip %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 %courselogs); use IO::Socket; use GDBM_File; use Apache::Constants qw(:common :http); @@ -660,6 +668,56 @@ sub log { return critical("log:$dom:$nam:$what",$hom); } +# ------------------------------------------------------------------ Course Log + +sub flushcourselogs { + &logthis('Flushing course log buffers'); + map { + my $crsid=$_; + if (&reply('log:'.$ENV{'course.'.$crsid.'.domain'}.':'. + $ENV{'course.'.$crsid.'.num'}.':'. + &escape($courselogs{$crsid}), + $ENV{'course.'.$crsid.'.home'}) eq 'ok') { + delete $courselogs{$crsid}; + } else { + &logthis('Failed to flush log buffer for '.$crsid); + if (length($courselogs{$crsid})>40000) { + &logthis("WARNING: Buffer for ".$crsid. + " exceeded maximum size, deleting."); + delete $courselogs{$crsid}; + } + } + } keys %courselogs; +} + +sub courselog { + my $what=shift; + $what=time.':'.$what; + unless ($ENV{'request.course.id'}) { return ''; } + if (defined $courselogs{$ENV{'request.course.id'}}) { + $courselogs{$ENV{'request.course.id'}}.='&'.$what; + } else { + $courselogs{$ENV{'request.course.id'}}.=$what; + } + if (length($courselogs{$ENV{'request.course.id'}})>4048) { + &flushcourselogs(); + } +} + +sub courseacclog { + my $fnsymb=shift; + unless ($ENV{'request.course.id'}) { return ''; } + my $what=$fnsymb.':'.$ENV{'user.name'}.':'.$ENV{'user.domain'}; + if ($what=~/(problem|exam|quiz|assess|survey|form)$/) { + map { + if ($_=~/^form\.(.*)/) { + $what.=':'.$1.'='.$ENV{$_}; + } + } keys %ENV; + } + &courselog($what); +} + # ----------------------------------------------------------- Check out an item sub checkout { @@ -683,9 +741,9 @@ sub checkout { $token=~s/^(\d+)\_.*\_(\d+)$/$1\*$2\*$lonhost/; $token=~tr/a-z/A-Z/; - my %infohash=('outtoken' => $token, - 'checkouttime' => $now, - 'outremote' => $ENV{'REMOTE_ADDR'}); + 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 ''; @@ -719,9 +777,20 @@ sub checkin { my ($tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)= split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost))); - my %infohash=('intoken' => $token, - 'checkintime' => $now, - 'inremote' => $ENV{'REMOTE_ADDR'}); + 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 ''; @@ -1121,6 +1190,12 @@ sub allowed { return 'F'; } +# Free bre to public access + + if ($priv eq 'bre') { + if (&metadata($uri,'copyright') eq 'public') { return 'F'; } + } + my $thisallowed=''; my $statecond=0; my $courseprivid=''; @@ -1193,6 +1268,7 @@ sub allowed { map { if ($_=~/^httpref\..*\*/) { my $pattern=$_; + $pattern=~s/^httpref\.\/res\///; $pattern=~s/\*/\[\^\/\]\+/g; $pattern=~s/\//\\\//g; if ($orguri=~/$pattern/) { @@ -1559,7 +1635,7 @@ sub modifystudent { return 'error: no such user'; } # -------------------------------------------------- Add student to course list - my $reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'. + $reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'. $ENV{'course.'.$cid.'.num'}.':classlist:'. &escape($uname.':'.$udom).'='. &escape($end.':'.$start), @@ -1624,7 +1700,7 @@ sub createcourse { my $reply=&reply('encrypt:makeuser:'.$udom.':'.$uname.':none::', $ENV{'user.home'}); unless ($reply eq 'ok') { return 'error: '.$reply; } - my $uhome=&homeserver($uname,$udom); + $uhome=&homeserver($uname,$udom); if (($uhome eq '') || ($uhome eq 'no_host')) { return 'error: no such course'; } @@ -2133,16 +2209,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"); @@ -2245,7 +2326,7 @@ sub unescape { # ================================================================ Main Program sub BEGIN { -if ($readit ne 'done') { +unless ($readit) { # ------------------------------------------------------------ Read access.conf { my $config=Apache::File->new("/etc/httpd/conf/access.conf"); @@ -2264,6 +2345,7 @@ 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; @@ -2289,8 +2371,10 @@ if ($readit ne 'done') { while (my $configline=<$config>) { chomp($configline); + if ($configline) { my ($role,$perm)=split(/ /,$configline); if ($perm ne '') { $pr{$role}=$perm; } + } } } @@ -2300,8 +2384,10 @@ if ($readit ne 'done') { while (my $configline=<$config>) { chomp($configline); + if ($configline) { my ($short,$plain)=split(/:/,$configline); if ($plain ne '') { $prp{$short}=$plain; } + } } }