version 1.224, 2004/08/06 10:27:53
|
version 1.230, 2004/08/16 11:44:10
|
Line 52 use LONCAPA::lonlocal;
|
Line 52 use LONCAPA::lonlocal;
|
use LONCAPA::lonssl; |
use LONCAPA::lonssl; |
use Fcntl qw(:flock); |
use Fcntl qw(:flock); |
|
|
my $DEBUG = 1; # Non zero to enable debug log entries. |
my $DEBUG = 0; # Non zero to enable debug log entries. |
|
|
my $status=''; |
my $status=''; |
my $lastlog=''; |
my $lastlog=''; |
Line 162 sub ResetStatistics {
|
Line 162 sub ResetStatistics {
|
$Failures = 0; |
$Failures = 0; |
} |
} |
|
|
|
|
|
|
#------------------------------------------------------------------------ |
#------------------------------------------------------------------------ |
# |
# |
# LocalConnection |
# LocalConnection |
Line 372 sub isClient {
|
Line 370 sub isClient {
|
# - This allows dynamic changes to the manager table |
# - This allows dynamic changes to the manager table |
# without the need to signal to the lond. |
# without the need to signal to the lond. |
# |
# |
|
|
sub ReadManagerTable { |
sub ReadManagerTable { |
|
|
# Clean out the old table first.. |
# Clean out the old table first.. |
Line 1509 sub change_password_handler {
|
Line 1506 sub change_password_handler {
|
register_handler("passwd", \&change_password_handler, 1, 1, 0); |
register_handler("passwd", \&change_password_handler, 1, 1, 0); |
|
|
|
|
|
# |
|
# Create a new user. User in this case means a lon-capa user. |
|
# The user must either already exist in some authentication realm |
|
# like kerberos or the /etc/passwd. If not, a user completely local to |
|
# this loncapa system is created. |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# Implicit inputs: |
|
# The authentication systems describe above have their own forms of implicit |
|
# input into the authentication process that are described above. |
|
sub add_user_handler { |
|
|
|
my ($cmd, $tail, $client) = @_; |
|
|
|
|
|
my ($udom,$uname,$umode,$npass)=split(/:/,$tail); |
|
my $userinput = $cmd.":".$tail; # Reconstruct the full request line. |
|
|
|
&Debug("cmd =".$cmd." $udom =".$udom." uname=".$uname); |
|
|
|
|
|
if($udom eq $currentdomainid) { # Reject new users for other domains... |
|
|
|
my $oldumask=umask(0077); |
|
chomp($npass); |
|
$npass=&unescape($npass); |
|
my $passfilename = &password_path($udom, $uname); |
|
&Debug("Password file created will be:".$passfilename); |
|
if (-e $passfilename) { |
|
&Failure( $client, "already_exists\n", $userinput); |
|
} else { |
|
my @fpparts=split(/\//,$passfilename); |
|
my $fpnow=$fpparts[0].'/'.$fpparts[1].'/'.$fpparts[2]; |
|
my $fperror=''; |
|
for (my $i=3;$i<= ($#fpparts-1);$i++) { |
|
$fpnow.='/'.$fpparts[$i]; |
|
unless (-e $fpnow) { |
|
&logthis("mkdir $fpnow"); |
|
unless (mkdir($fpnow,0777)) { |
|
$fperror="error: ".($!+0)." mkdir failed while attempting " |
|
."makeuser"; |
|
} |
|
} |
|
} |
|
unless ($fperror) { |
|
my $result=&make_passwd_file($uname, $umode,$npass, $passfilename); |
|
&Reply($client, $result, $userinput); #BUGBUG - could be fail |
|
} else { |
|
&Failure($client, "$fperror\n", $userinput); |
|
} |
|
} |
|
umask($oldumask); |
|
} else { |
|
&Failure($client, "not_right_domain\n", |
|
$userinput); # Even if we are multihomed. |
|
|
|
} |
|
return 1; |
|
|
|
} |
|
®ister_handler("makeuser", \&add_user_handler, 1, 1, 0); |
|
|
|
# |
|
# Change the authentication method of a user. Note that this may |
|
# also implicitly change the user's password if, for example, the user is |
|
# joining an existing authentication realm. Known authentication realms at |
|
# this time are: |
|
# internal - Purely internal password file (only loncapa knows this user) |
|
# local - Institutionally written authentication module. |
|
# unix - Unix user (/etc/passwd with or without /etc/shadow). |
|
# kerb4 - kerberos version 4 |
|
# kerb5 - kerberos version 5 |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# Implicit inputs: |
|
# The authentication systems describe above have their own forms of implicit |
|
# input into the authentication process that are described above. |
|
# |
|
sub change_authentication_handler { |
|
|
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; # Reconstruct user input. |
|
|
|
my ($udom,$uname,$umode,$npass)=split(/:/,$tail); |
|
&Debug("cmd = ".$cmd." domain= ".$udom."uname =".$uname." umode= ".$umode); |
|
if ($udom ne $currentdomainid) { |
|
&Failure( $client, "not_right_domain\n", $client); |
|
} else { |
|
|
|
chomp($npass); |
|
|
|
$npass=&unescape($npass); |
|
my $passfilename = &password_path($udom, $uname); |
|
if ($passfilename) { # Not allowed to create a new user!! |
|
my $result=&make_passwd_file($uname, $umode,$npass,$passfilename); |
|
&Reply($client, $result, $userinput); |
|
} else { |
|
&Failure($client, "non_authorized", $userinput); # Fail the user now. |
|
} |
|
} |
|
return 1; |
|
} |
|
®ister_handler("changeuserauth", \&change_authentication_handler, 1,1, 0); |
|
|
|
# |
|
# Determines if this is the home server for a user. The home server |
|
# for a user will have his/her lon-capa passwd file. Therefore all we need |
|
# to do is determine if this file exists. |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# Implicit inputs: |
|
# The authentication systems describe above have their own forms of implicit |
|
# input into the authentication process that are described above. |
|
# |
|
sub is_home_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my ($udom,$uname)=split(/:/,$tail); |
|
chomp($uname); |
|
my $passfile = &password_filename($udom, $uname); |
|
if($passfile) { |
|
&Reply( $client, "found\n", $userinput); |
|
} else { |
|
&Failure($client, "not_found\n", $userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("home", \&is_home_handler, 0,1,0); |
|
|
|
# |
|
# Process an update request for a resource?? I think what's going on here is |
|
# that a resource has been modified that we hold a subscription to. |
|
# If the resource is not local, then we must update, or at least invalidate our |
|
# cached copy of the resource. |
|
# FUTURE WORK: |
|
# I need to look at this logic carefully. My druthers would be to follow |
|
# typical caching logic, and simple invalidate the cache, drop any subscription |
|
# an let the next fetch start the ball rolling again... however that may |
|
# actually be more difficult than it looks given the complex web of |
|
# proxy servers. |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# Implicit inputs: |
|
# The authentication systems describe above have their own forms of implicit |
|
# input into the authentication process that are described above. |
|
# |
|
sub update_resource_handler { |
|
|
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my $fname= $tail; # This allows interactive testing |
|
|
|
|
|
my $ownership=ishome($fname); |
|
if ($ownership eq 'not_owner') { |
|
if (-e $fname) { |
|
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, |
|
$atime,$mtime,$ctime,$blksize,$blocks)=stat($fname); |
|
my $now=time; |
|
my $since=$now-$atime; |
|
if ($since>$perlvar{'lonExpire'}) { |
|
my $reply=&reply("unsub:$fname","$clientname"); |
|
unlink("$fname"); |
|
} else { |
|
my $transname="$fname.in.transfer"; |
|
my $remoteurl=&reply("sub:$fname","$clientname"); |
|
my $response; |
|
alarm(120); |
|
{ |
|
my $ua=new LWP::UserAgent; |
|
my $request=new HTTP::Request('GET',"$remoteurl"); |
|
$response=$ua->request($request,$transname); |
|
} |
|
alarm(0); |
|
if ($response->is_error()) { |
|
unlink($transname); |
|
my $message=$response->status_line; |
|
&logthis("LWP GET: $message for $fname ($remoteurl)"); |
|
} else { |
|
if ($remoteurl!~/\.meta$/) { |
|
alarm(120); |
|
{ |
|
my $ua=new LWP::UserAgent; |
|
my $mrequest=new HTTP::Request('GET',$remoteurl.'.meta'); |
|
my $mresponse=$ua->request($mrequest,$fname.'.meta'); |
|
if ($mresponse->is_error()) { |
|
unlink($fname.'.meta'); |
|
} |
|
} |
|
alarm(0); |
|
} |
|
rename($transname,$fname); |
|
} |
|
} |
|
&Reply( $client, "ok\n", $userinput); |
|
} else { |
|
&Failure($client, "not_found\n", $userinput); |
|
} |
|
} else { |
|
&Failure($client, "rejected\n", $userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("update", \&update_resource_handler, 0 ,1, 0); |
|
|
|
# |
|
# Fetch a user file from a remote server to the user's home directory |
|
# userfiles subdir. |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub fetch_user_file_handler { |
|
|
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
my $fname = $tail; |
|
my ($udom,$uname,$ufile)=split(/\//,$fname); |
|
my $udir=&propath($udom,$uname).'/userfiles'; |
|
unless (-e $udir) { |
|
mkdir($udir,0770); |
|
} |
|
if (-e $udir) { |
|
$ufile=~s/^[\.\~]+//; |
|
$ufile=~s/\///g; |
|
my $destname=$udir.'/'.$ufile; |
|
my $transname=$udir.'/'.$ufile.'.in.transit'; |
|
my $remoteurl='http://'.$clientip.'/userfiles/'.$fname; |
|
my $response; |
|
alarm(120); |
|
{ |
|
my $ua=new LWP::UserAgent; |
|
my $request=new HTTP::Request('GET',"$remoteurl"); |
|
$response=$ua->request($request,$transname); |
|
} |
|
alarm(0); |
|
if ($response->is_error()) { |
|
unlink($transname); |
|
my $message=$response->status_line; |
|
&logthis("LWP GET: $message for $fname ($remoteurl)"); |
|
&Failure($client, "failed\n", $userinput); |
|
} else { |
|
if (!rename($transname,$destname)) { |
|
&logthis("Unable to move $transname to $destname"); |
|
unlink($transname); |
|
&Failure($client, "failed\n", $userinput); |
|
} else { |
|
&Reply($client, "ok\n", $userinput); |
|
} |
|
} |
|
} else { |
|
&Failure($client, "not_home\n", $userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("fetchuserfile", \&fetch_user_file_handler, 0, 1, 0); |
|
|
|
# |
|
# Remove a file from a user's home directory userfiles subdirectory. |
|
# Parameters: |
|
# cmd - the Lond request keyword that got us here. |
|
# tail - the part of the command past the keyword. |
|
# client- File descriptor connected with the client. |
|
# |
|
# Returns: |
|
# 1 - Continue processing. |
|
|
|
sub remove_user_file_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my ($fname) = split(/:/, $tail); # Get rid of any tailing :'s lonc may have sent. |
|
|
|
my ($udom,$uname,$ufile) = ($fname =~ m|^([^/]+)/([^/]+)/(.+)$|); |
|
if ($ufile =~m|/\.\./|) { |
|
# any files paths with /../ in them refuse |
|
# to deal with |
|
&Failure($client, "refused\n", "$cmd:$tail"); |
|
} else { |
|
my $udir = &propath($udom,$uname); |
|
if (-e $udir) { |
|
my $file=$udir.'/userfiles/'.$ufile; |
|
if (-e $file) { |
|
unlink($file); |
|
if (-e $file) { |
|
&Failure($client, "failed\n", "$cmd:$tail"); |
|
} else { |
|
&Reply($client, "ok\n", "$cmd:$tail"); |
|
} |
|
} else { |
|
&Failure($client, "not_found\n", "$cmd:$tail"); |
|
} |
|
} else { |
|
&Failure($client, "not_home\n", "$cmd:$tail"); |
|
} |
|
} |
|
return 1; |
|
} |
|
®ister_handler("removeuserfile", \&remove_user_file_handler, 0,1,0); |
|
|
|
|
|
# |
|
# Authenticate access to a user file by checking the user's |
|
# session token(?) |
|
# |
|
# Parameters: |
|
# cmd - The request keyword that dispatched to tus. |
|
# tail - The tail of the request (colon separated parameters). |
|
# client - Filehandle open on the client. |
|
# Return: |
|
# 1. |
|
|
|
sub token_auth_user_file_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my ($fname, $session) = split(/:/, $tail); |
|
|
|
chomp($session); |
|
my $reply='non_auth'; |
|
if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'. |
|
$session.'.id')) { |
|
while (my $line=<ENVIN>) { |
|
if ($line=~ m|userfile\.\Q$fname\E\=|) { $reply='ok'; } |
|
} |
|
close(ENVIN); |
|
&Reply($client, $reply); |
|
} else { |
|
&Failure($client, "invalid_token\n", "$cmd:$tail"); |
|
} |
|
return 1; |
|
|
|
} |
|
|
|
®ister_handler("tokenauthuserfile", \&token_auth_user_file_handler, 0,1,0); |
|
|
|
|
|
# |
|
# Unsubscribe from a resource. |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub unsubscribe_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput= "$cmd:$tail"; |
|
|
|
my ($fname) = split(/:/,$tail); # Split in case there's extrs. |
|
|
|
&Debug("Unsubscribing $fname"); |
|
if (-e $fname) { |
|
&Debug("Exists"); |
|
&Reply($client, &unsub($fname,$clientip), $userinput); |
|
} else { |
|
&Failure($client, "not_found\n", $userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("unsub", \&unsubscribe_handler, 0, 1, 0); |
|
# Subscribe to a resource |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub subscribe_handler { |
|
my ($cmd, $tail, $client)= @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
&Reply( $client, &subscribe($userinput,$clientip), $userinput); |
|
|
|
return 1; |
|
} |
|
®ister_handler("sub", \&subscribe_handler, 0, 1, 0); |
|
|
|
# |
|
# Determine the version of a resource (?) Or is it return |
|
# the top version of the resource? Not yet clear from the |
|
# code in currentversion. |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub current_version_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput= "$cmd:$tail"; |
|
|
|
my $fname = $tail; |
|
&Reply( $client, ¤tversion($fname)."\n", $userinput); |
|
return 1; |
|
|
|
} |
|
®ister_handler("currentversion", \¤t_version_handler, 0, 1, 0); |
|
|
|
# Make an entry in a user's activity log. |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub activity_log_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
|
|
my $userinput= "$cmd:$tail"; |
|
|
|
my ($udom,$uname,$what)=split(/:/,$tail); |
|
chomp($what); |
|
my $proname=&propath($udom,$uname); |
|
my $now=time; |
|
my $hfh; |
|
if ($hfh=IO::File->new(">>$proname/activity.log")) { |
|
print $hfh "$now:$clientname:$what\n"; |
|
&Reply( $client, "ok\n", $userinput); |
|
} else { |
|
&Failure($client, "error: ".($!+0)." IO::File->new Failed " |
|
."while attempting log\n", |
|
$userinput); |
|
} |
|
|
|
return 1; |
|
} |
|
register_handler("log", \&activity_log_handler, 0, 1, 0); |
|
|
|
# |
|
# Put a namespace entry in a user profile hash. |
|
# My druthers would be for this to be an encrypted interaction too. |
|
# anything that might be an inadvertent covert channel about either |
|
# user authentication or user personal information.... |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub put_user_profile_entry { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my ($udom,$uname,$namespace,$what) =split(/:/,$tail); |
|
if ($namespace ne 'roles') { |
|
chomp($what); |
|
my $hashref = &tie_user_hash($udom, $uname, $namespace, |
|
&GDBM_WRCREAT(),"P",$what); |
|
if($hashref) { |
|
my @pairs=split(/\&/,$what); |
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
$hashref->{$key}=$value; |
|
} |
|
if (untie(%$hashref)) { |
|
&Reply( $client, "ok\n", $userinput); |
|
} else { |
|
&Failure($client, "error: ".($!+0)." untie(GDBM) failed ". |
|
"while attempting put\n", |
|
$userinput); |
|
} |
|
} else { |
|
&Failure( $client, "error: ".($!)." tie(GDBM) Failed ". |
|
"while attempting put\n", $userinput); |
|
} |
|
} else { |
|
&Failure( $client, "refused\n", $userinput); |
|
} |
|
|
|
return 1; |
|
} |
|
®ister_handler("put", \&put_user_profile_entry, 0, 1, 0); |
|
|
|
# |
|
# Increment a profile entry in the user history file. |
|
# The history contains keyword value pairs. In this case, |
|
# The value itself is a pair of numbers. The first, the current value |
|
# the second an increment that this function applies to the current |
|
# value. |
|
# |
|
# Parameters: |
|
# $cmd - The command that got us here. |
|
# $tail - Tail of the command (remaining parameters). |
|
# $client - File descriptor connected to client. |
|
# Returns |
|
# 0 - Requested to exit, caller should shut down. |
|
# 1 - Continue processing. |
|
# |
|
sub increment_user_value_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my ($udom,$uname,$namespace,$what) =split(/:/,$tail); |
|
if ($namespace ne 'roles') { |
|
chomp($what); |
|
my $hashref = &tie_user_hash($udom, $uname, |
|
$namespace, &GDBM_WRCREAT(), |
|
"P",$what); |
|
if ($hashref) { |
|
my @pairs=split(/\&/,$what); |
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
# We could check that we have a number... |
|
if (! defined($value) || $value eq '') { |
|
$value = 1; |
|
} |
|
$hashref->{$key}+=$value; |
|
} |
|
if (untie(%$hashref)) { |
|
&Reply( $client, "ok\n", $userinput); |
|
} else { |
|
&Failure($client, "error: ".($!+0)." untie(GDBM) failed ". |
|
"while attempting inc\n", $userinput); |
|
} |
|
} else { |
|
&Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". |
|
"while attempting inc\n", $userinput); |
|
} |
|
} else { |
|
&Failure($client, "refused\n", $userinput); |
|
} |
|
|
|
return 1; |
|
} |
|
®ister_handler("inc", \&increment_user_value_handler, 0, 1, 0); |
|
|
|
|
|
# |
|
# Put a new role for a user. Roles are LonCAPA's packaging of permissions. |
|
# Each 'role' a user has implies a set of permissions. Adding a new role |
|
# for a person grants the permissions packaged with that role |
|
# to that user when the role is selected. |
|
# |
|
# Parameters: |
|
# $cmd - The command string (rolesput). |
|
# $tail - The remainder of the request line. For rolesput this |
|
# consists of a colon separated list that contains: |
|
# The domain and user that is granting the role (logged). |
|
# The domain and user that is getting the role. |
|
# The roles being granted as a set of & separated pairs. |
|
# each pair a key value pair. |
|
# $client - File descriptor connected to the client. |
|
# Returns: |
|
# 0 - If the daemon should exit |
|
# 1 - To continue processing. |
|
# |
|
# |
|
sub roles_put_handler { |
|
my ($cmd, $tail, $client) = @_; |
|
|
|
my $userinput = "$cmd:$tail"; |
|
|
|
my ( $exedom, $exeuser, $udom, $uname, $what) = split(/:/,$tail); |
|
|
|
|
|
my $namespace='roles'; |
|
chomp($what); |
|
my $hashref = &tie_user_hash($udom, $uname, $namespace, |
|
&GDBM_WRCREAT(), "P", |
|
"$exedom:$exeuser:$what"); |
|
# |
|
# Log the attempt to set a role. The {}'s here ensure that the file |
|
# handle is open for the minimal amount of time. Since the flush |
|
# is done on close this improves the chances the log will be an un- |
|
# corrupted ordered thing. |
|
if ($hashref) { |
|
my @pairs=split(/\&/,$what); |
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
&manage_permissions($key, $udom, $uname, |
|
&get_auth_type( $udom, $uname)); |
|
$hashref->{$key}=$value; |
|
} |
|
if (untie($hashref)) { |
|
&Reply($client, "ok\n", $userinput); |
|
} else { |
|
&Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". |
|
"while attempting rolesput\n", $userinput); |
|
} |
|
} else { |
|
&Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". |
|
"while attempting rolesput\n", $userinput); |
|
} |
|
return 1; |
|
} |
|
®ister_handler("rolesput", \&roles_put_handler, 1,1,0); # Encoded client only. |
|
|
|
# |
#--------------------------------------------------------------- |
#--------------------------------------------------------------- |
# |
# |
# Getting, decoding and dispatching requests: |
# Getting, decoding and dispatching requests: |
Line 1519 register_handler("passwd", \&change_pass
|
Line 2157 register_handler("passwd", \&change_pass
|
# Gets a Request message from the client. The transaction |
# Gets a Request message from the client. The transaction |
# is defined as a 'line' of text. We remove the new line |
# is defined as a 'line' of text. We remove the new line |
# from the text line. |
# from the text line. |
# |
# |
sub get_request { |
sub get_request { |
my $input = <$client>; |
my $input = <$client>; |
chomp($input); |
chomp($input); |
Line 1623 sub process_request {
|
Line 2261 sub process_request {
|
#------------------- Commands not yet in spearate handlers. -------------- |
#------------------- Commands not yet in spearate handlers. -------------- |
|
|
|
|
|
|
# -------------------------------------------------------------------- makeuser |
|
if ($userinput =~ /^makeuser/) { # encoded and client. |
|
&Debug("Make user received"); |
|
my $oldumask=umask(0077); |
|
if (($wasenc==1) && isClient) { |
|
my |
|
($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput); |
|
&Debug("cmd =".$cmd." $udom =".$udom. |
|
" uname=".$uname); |
|
chomp($npass); |
|
$npass=&unescape($npass); |
|
my $proname=propath($udom,$uname); |
|
my $passfilename="$proname/passwd"; |
|
&Debug("Password file created will be:". |
|
$passfilename); |
|
if (-e $passfilename) { |
|
print $client "already_exists\n"; |
|
} elsif ($udom ne $currentdomainid) { |
|
print $client "not_right_domain\n"; |
|
} else { |
|
my @fpparts=split(/\//,$proname); |
|
my $fpnow=$fpparts[0].'/'.$fpparts[1].'/'.$fpparts[2]; |
|
my $fperror=''; |
|
for (my $i=3;$i<=$#fpparts;$i++) { |
|
$fpnow.='/'.$fpparts[$i]; |
|
unless (-e $fpnow) { |
|
unless (mkdir($fpnow,0777)) { |
|
$fperror="error: ".($!+0) |
|
." mkdir failed while attempting " |
|
."makeuser"; |
|
} |
|
} |
|
} |
|
unless ($fperror) { |
|
my $result=&make_passwd_file($uname, $umode,$npass, |
|
$passfilename); |
|
print $client $result; |
|
} else { |
|
print $client "$fperror\n"; |
|
} |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
umask($oldumask); |
|
# -------------------------------------------------------------- changeuserauth |
|
} elsif ($userinput =~ /^changeuserauth/) { # encoded & client |
|
&Debug("Changing authorization"); |
|
if (($wasenc==1) && isClient) { |
|
my |
|
($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput); |
|
chomp($npass); |
|
&Debug("cmd = ".$cmd." domain= ".$udom. |
|
"uname =".$uname." umode= ".$umode); |
|
$npass=&unescape($npass); |
|
my $proname=&propath($udom,$uname); |
|
my $passfilename="$proname/passwd"; |
|
if ($udom ne $currentdomainid) { |
|
print $client "not_right_domain\n"; |
|
} else { |
|
my $result=&make_passwd_file($uname, $umode,$npass, |
|
$passfilename); |
|
Reply($client, $result, $userinput); |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ------------------------------------------------------------------------ home |
|
} elsif ($userinput =~ /^home/) { # client clear or encoded |
|
if(isClient) { |
|
my ($cmd,$udom,$uname)=split(/:/,$userinput); |
|
chomp($uname); |
|
my $proname=propath($udom,$uname); |
|
if (-e $proname) { |
|
print $client "found\n"; |
|
} else { |
|
print $client "not_found\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ---------------------------------------------------------------------- update |
|
} elsif ($userinput =~ /^update/) { # client clear or encoded. |
|
if(isClient) { |
|
my ($cmd,$fname)=split(/:/,$userinput); |
|
my $ownership=ishome($fname); |
|
if ($ownership eq 'not_owner') { |
|
if (-e $fname) { |
|
my ($dev,$ino,$mode,$nlink, |
|
$uid,$gid,$rdev,$size, |
|
$atime,$mtime,$ctime, |
|
$blksize,$blocks)=stat($fname); |
|
my $now=time; |
|
my $since=$now-$atime; |
|
if ($since>$perlvar{'lonExpire'}) { |
|
my $reply= |
|
&reply("unsub:$fname","$clientname"); |
|
unlink("$fname"); |
|
} else { |
|
my $transname="$fname.in.transfer"; |
|
my $remoteurl= |
|
&reply("sub:$fname","$clientname"); |
|
my $response; |
|
{ |
|
my $ua=new LWP::UserAgent; |
|
my $request=new HTTP::Request('GET',"$remoteurl"); |
|
$response=$ua->request($request,$transname); |
|
} |
|
if ($response->is_error()) { |
|
unlink($transname); |
|
my $message=$response->status_line; |
|
&logthis( |
|
"LWP GET: $message for $fname ($remoteurl)"); |
|
} else { |
|
if ($remoteurl!~/\.meta$/) { |
|
my $ua=new LWP::UserAgent; |
|
my $mrequest= |
|
new HTTP::Request('GET',$remoteurl.'.meta'); |
|
my $mresponse= |
|
$ua->request($mrequest,$fname.'.meta'); |
|
if ($mresponse->is_error()) { |
|
unlink($fname.'.meta'); |
|
} |
|
} |
|
rename($transname,$fname); |
|
} |
|
} |
|
print $client "ok\n"; |
|
} else { |
|
print $client "not_found\n"; |
|
} |
|
} else { |
|
print $client "rejected\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# -------------------------------------- fetch a user file from a remote server |
|
} elsif ($userinput =~ /^fetchuserfile/) { # Client clear or enc. |
|
if(isClient) { |
|
my ($cmd,$fname)=split(/:/,$userinput); |
|
my ($udom,$uname,$ufile) = ($fname =~ m|^([^/]+)/([^/]+)/(.+)$|); |
|
my $udir=propath($udom,$uname).'/userfiles'; |
|
unless (-e $udir) { mkdir($udir,0770); } |
|
if (-e $udir) { |
|
$ufile=~s/^[\.\~]+//; |
|
my $path = $udir; |
|
if ($ufile =~m|(.+)/([^/]+)$|) { |
|
my @parts=split('/',$1); |
|
foreach my $part (@parts) { |
|
$path .= '/'.$part; |
|
if ((-e $path)!=1) { |
|
mkdir($path,0770); |
|
} |
|
} |
|
} |
|
my $destname=$udir.'/'.$ufile; |
|
my $transname=$udir.'/'.$ufile.'.in.transit'; |
|
my $remoteurl='http://'.$clientip.'/userfiles/'.$fname; |
|
my $response; |
|
{ |
|
my $ua=new LWP::UserAgent; |
|
my $request=new HTTP::Request('GET',"$remoteurl"); |
|
$response=$ua->request($request,$transname); |
|
} |
|
if ($response->is_error()) { |
|
unlink($transname); |
|
my $message=$response->status_line; |
|
&logthis("LWP GET: $message for $fname ($remoteurl)"); |
|
print $client "failed\n"; |
|
} else { |
|
if (!rename($transname,$destname)) { |
|
&logthis("Unable to move $transname to $destname"); |
|
unlink($transname); |
|
print $client "failed\n"; |
|
} else { |
|
print $client "ok\n"; |
|
} |
|
} |
|
} else { |
|
print $client "not_home\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
} |
|
# --------------------------------------------------------- remove a user file |
|
} elsif ($userinput =~ /^removeuserfile/) { # Client clear or enc. |
|
if(isClient) { |
|
my ($cmd,$fname)=split(/:/,$userinput); |
|
my ($udom,$uname,$ufile) = ($fname =~ m|^([^/]+)/([^/]+)/(.+)$|); |
|
&logthis("$udom - $uname - $ufile"); |
|
if ($ufile =~m|/\.\./|) { |
|
# any files paths with /../ in them refuse |
|
# to deal with |
|
print $client "refused\n"; |
|
} else { |
|
my $udir=propath($udom,$uname); |
|
if (-e $udir) { |
|
my $file=$udir.'/userfiles/'.$ufile; |
|
if (-e $file) { |
|
unlink($file); |
|
if (-e $file) { |
|
print $client "failed\n"; |
|
} else { |
|
print $client "ok\n"; |
|
} |
|
} else { |
|
print $client "not_found\n"; |
|
} |
|
} else { |
|
print $client "not_home\n"; |
|
} |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
} |
|
# ------------------------------------------ authenticate access to a user file |
|
} elsif ($userinput =~ /^tokenauthuserfile/) { # Client only |
|
if(isClient) { |
|
my ($cmd,$fname,$session)=split(/:/,$userinput); |
|
chomp($session); |
|
my $reply='non_auth'; |
|
if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'. |
|
$session.'.id')) { |
|
while (my $line=<ENVIN>) { |
|
if ($line=~ m|userfile\.\Q$fname\E\=|) { $reply='ok'; } |
|
} |
|
close(ENVIN); |
|
print $client $reply."\n"; |
|
} else { |
|
print $client "invalid_token\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ----------------------------------------------------------------- unsubscribe |
|
} elsif ($userinput =~ /^unsub/) { |
|
if(isClient) { |
|
my ($cmd,$fname)=split(/:/,$userinput); |
|
if (-e $fname) { |
|
print $client &unsub($fname,$clientip); |
|
} else { |
|
print $client "not_found\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ------------------------------------------------------------------- subscribe |
|
} elsif ($userinput =~ /^sub/) { |
|
if(isClient) { |
|
print $client &subscribe($userinput,$clientip); |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ------------------------------------------------------------- current version |
|
} elsif ($userinput =~ /^currentversion/) { |
|
if(isClient) { |
|
my ($cmd,$fname)=split(/:/,$userinput); |
|
print $client ¤tversion($fname)."\n"; |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ------------------------------------------------------------------------- log |
|
} elsif ($userinput =~ /^log/) { |
|
if(isClient) { |
|
my ($cmd,$udom,$uname,$what)=split(/:/,$userinput); |
|
chomp($what); |
|
my $proname=propath($udom,$uname); |
|
my $now=time; |
|
{ |
|
my $hfh; |
|
if ($hfh=IO::File->new(">>$proname/activity.log")) { |
|
print $hfh "$now:$clientname:$what\n"; |
|
print $client "ok\n"; |
|
} else { |
|
print $client "error: ".($!+0) |
|
." IO::File->new Failed " |
|
."while attempting log\n"; |
|
} |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ------------------------------------------------------------------------- put |
|
} elsif ($userinput =~ /^put/) { |
|
if(isClient) { |
|
my ($cmd,$udom,$uname,$namespace,$what) |
|
=split(/:/,$userinput,5); |
|
$namespace=~s/\//\_/g; |
|
$namespace=~s/\W//g; |
|
if ($namespace ne 'roles') { |
|
chomp($what); |
|
my $proname=propath($udom,$uname); |
|
my $now=time; |
|
my @pairs=split(/\&/,$what); |
|
my %hash; |
|
if (tie(%hash,'GDBM_File', |
|
"$proname/$namespace.db", |
|
&GDBM_WRCREAT(),0640)) { |
|
unless ($namespace=~/^nohist\_/) { |
|
my $hfh; |
|
if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { print $hfh "P:$now:$what\n"; } |
|
} |
|
|
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
$hash{$key}=$value; |
|
} |
|
if (untie(%hash)) { |
|
print $client "ok\n"; |
|
} else { |
|
print $client "error: ".($!+0) |
|
." untie(GDBM) failed ". |
|
"while attempting put\n"; |
|
} |
|
} else { |
|
print $client "error: ".($!) |
|
." tie(GDBM) Failed ". |
|
"while attempting put\n"; |
|
} |
|
} else { |
|
print $client "refused\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# ------------------------------------------------------------------- inc |
|
} elsif ($userinput =~ /^inc:/) { |
|
if(isClient) { |
|
my ($cmd,$udom,$uname,$namespace,$what) |
|
=split(/:/,$userinput); |
|
$namespace=~s/\//\_/g; |
|
$namespace=~s/\W//g; |
|
if ($namespace ne 'roles') { |
|
chomp($what); |
|
my $proname=propath($udom,$uname); |
|
my $now=time; |
|
my @pairs=split(/\&/,$what); |
|
my %hash; |
|
if (tie(%hash,'GDBM_File', |
|
"$proname/$namespace.db", |
|
&GDBM_WRCREAT(),0640)) { |
|
unless ($namespace=~/^nohist\_/) { |
|
my $hfh; |
|
if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { print $hfh "P:$now:$what\n"; } |
|
} |
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
# We could check that we have a number... |
|
if (! defined($value) || $value eq '') { |
|
$value = 1; |
|
} |
|
$hash{$key}+=$value; |
|
} |
|
if (untie(%hash)) { |
|
print $client "ok\n"; |
|
} else { |
|
print $client "error: ".($!+0) |
|
." untie(GDBM) failed ". |
|
"while attempting inc\n"; |
|
} |
|
} else { |
|
print $client "error: ".($!) |
|
." tie(GDBM) Failed ". |
|
"while attempting inc\n"; |
|
} |
|
} else { |
|
print $client "refused\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# -------------------------------------------------------------------- rolesput |
|
} elsif ($userinput =~ /^rolesput/) { |
|
if(isClient) { |
|
&Debug("rolesput"); |
|
if ($wasenc==1) { |
|
my ($cmd,$exedom,$exeuser,$udom,$uname,$what) |
|
=split(/:/,$userinput); |
|
&Debug("cmd = ".$cmd." exedom= ".$exedom. |
|
"user = ".$exeuser." udom=".$udom. |
|
"what = ".$what); |
|
my $namespace='roles'; |
|
chomp($what); |
|
my $proname=propath($udom,$uname); |
|
my $now=time; |
|
my @pairs=split(/\&/,$what); |
|
my %hash; |
|
if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) { |
|
{ |
|
my $hfh; |
|
if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { |
|
print $hfh "P:$now:$exedom:$exeuser:$what\n"; |
|
} |
|
} |
|
|
|
foreach my $pair (@pairs) { |
|
my ($key,$value)=split(/=/,$pair); |
|
&ManagePermissions($key, $udom, $uname, |
|
&get_auth_type( $udom, |
|
$uname)); |
|
$hash{$key}=$value; |
|
} |
|
if (untie(%hash)) { |
|
print $client "ok\n"; |
|
} else { |
|
print $client "error: ".($!+0) |
|
." untie(GDBM) Failed ". |
|
"while attempting rolesput\n"; |
|
} |
|
} else { |
|
print $client "error: ".($!+0) |
|
." tie(GDBM) Failed ". |
|
"while attempting rolesput\n"; |
|
} |
|
} else { |
|
print $client "refused\n"; |
|
} |
|
} else { |
|
Reply($client, "refused\n", $userinput); |
|
|
|
} |
|
# -------------------------------------------------------------------- rolesdel |
# -------------------------------------------------------------------- rolesdel |
} elsif ($userinput =~ /^rolesdel/) { |
if ($userinput =~ /^rolesdel/) { |
if(isClient) { |
if(isClient) { |
&Debug("rolesdel"); |
&Debug("rolesdel"); |
if ($wasenc==1) { |
if ($wasenc==1) { |
Line 3005 sub register_handler {
|
Line 3209 sub register_handler {
|
|
|
$Dispatcher{$request_name} = \@entry; |
$Dispatcher{$request_name} = \@entry; |
|
|
|
|
} |
} |
|
|
|
|
Line 3052 sub catchexception {
|
Line 3255 sub catchexception {
|
$server->close(); |
$server->close(); |
die($error); |
die($error); |
} |
} |
|
|
sub timeout { |
sub timeout { |
&status("Handling Timeout"); |
&status("Handling Timeout"); |
&logthis("<font color='red'>CRITICAL: TIME OUT ".$$."</font>"); |
&logthis("<font color='red'>CRITICAL: TIME OUT ".$$."</font>"); |
Line 3060 sub timeout {
|
Line 3262 sub timeout {
|
} |
} |
# -------------------------------- Set signal handlers to record abnormal exits |
# -------------------------------- Set signal handlers to record abnormal exits |
|
|
|
|
$SIG{'QUIT'}=\&catchexception; |
$SIG{'QUIT'}=\&catchexception; |
$SIG{__DIE__}=\&catchexception; |
$SIG{__DIE__}=\&catchexception; |
|
|
Line 3812 sub make_new_child {
|
Line 4015 sub make_new_child {
|
# user - Name of the user for which the role is being put. |
# user - Name of the user for which the role is being put. |
# authtype - The authentication type associated with the user. |
# authtype - The authentication type associated with the user. |
# |
# |
sub ManagePermissions |
sub manage_permissions |
{ |
{ |
|
|
my ($request, $domain, $user, $authtype) = @_; |
my ($request, $domain, $user, $authtype) = @_; |
Line 4653 Place in B<logs/lond.log>
|
Line 4856 Place in B<logs/lond.log>
|
|
|
stores hash in namespace |
stores hash in namespace |
|
|
=item rolesput |
=item rolesputy |
|
|
put a role into a user's environment |
put a role into a user's environment |
|
|