--- loncom/lond 2004/09/03 10:13:59 1.248
+++ loncom/lond 2005/06/03 18:23:19 1.284
@@ -2,7 +2,7 @@
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
#
-# $Id: lond,v 1.248 2004/09/03 10:13:59 foxr Exp $
+# $Id: lond,v 1.284 2005/06/03 18:23:19 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -46,6 +46,7 @@ use Authen::Krb5;
use lib '/home/httpd/lib/perl/';
use localauth;
use localenroll;
+use localstudentphoto;
use File::Copy;
use LONCAPA::ConfigFileEdit;
use LONCAPA::lonlocal;
@@ -57,14 +58,13 @@ my $DEBUG = 0; # Non zero to ena
my $status='';
my $lastlog='';
-my $VERSION='$Revision: 1.248 $'; #' stupid emacs
+my $VERSION='$Revision: 1.284 $'; #' stupid emacs
my $remoteVERSION;
my $currenthostid="default";
my $currentdomainid;
my $client;
my $clientip; # IP address of client.
-my $clientdns; # DNS name of client.
my $clientname; # LonCAPA name of client.
my $server;
@@ -177,7 +177,6 @@ sub ResetStatistics {
# $initcmd - The full text of the init command.
#
# Implicit inputs:
-# $clientdns - The DNS name of the remote client.
# $thisserver - Our DNS name.
#
# Returns:
@@ -186,10 +185,10 @@ sub ResetStatistics {
#
sub LocalConnection {
my ($Socket, $initcmd) = @_;
- Debug("Attempting local connection: $initcmd client: $clientdns me: $thisserver");
- if($clientdns ne $thisserver) {
+ Debug("Attempting local connection: $initcmd client: $clientip me: $thisserver");
+ if($clientip ne "127.0.0.1") {
&logthis(' LocalConnection rejecting non local: '
- ."$clientdns ne $thisserver ");
+ ."$clientip ne $thisserver ");
close $Socket;
return undef;
} else {
@@ -331,8 +330,43 @@ sub InsecureConnection {
}
-
#
+# Safely execute a command (as long as it's not a shel command and doesn
+# not require/rely on shell escapes. The function operates by doing a
+# a pipe based fork and capturing stdout and stderr from the pipe.
+#
+# Formal Parameters:
+# $line - A line of text to be executed as a command.
+# Returns:
+# The output from that command. If the output is multiline the caller
+# must know how to split up the output.
+#
+#
+sub execute_command {
+ my ($line) = @_;
+ my @words = split(/\s/, $line); # Bust the command up into words.
+ my $output = "";
+
+ my $pid = open(CHILD, "-|");
+
+ if($pid) { # Parent process
+ Debug("In parent process for execute_command");
+ my @data = ; # Read the child's outupt...
+ close CHILD;
+ foreach my $output_line (@data) {
+ Debug("Adding $output_line");
+ $output .= $output_line; # Presumably has a \n on it.
+ }
+
+ } else { # Child process
+ close (STDERR);
+ open (STDERR, ">&STDOUT");# Combine stderr, and stdout...
+ exec(@words); # won't return.
+ }
+ return $output;
+}
+
+
# GetCertificate: Given a transaction that requires a certificate,
# this function will extract the certificate from the transaction
# request. Note that at this point, the only concept of a certificate
@@ -438,39 +472,11 @@ sub CopyFile {
my ($oldfile, $newfile) = @_;
- # The file must exist:
-
- if(-e $oldfile) {
-
- # Read the old file.
-
- my $oldfh = IO::File->new("< $oldfile");
- if(!$oldfh) {
- return 0;
- }
- my @contents = <$oldfh>; # Suck in the entire file.
-
- # write the backup file:
-
- my $newfh = IO::File->new("> $newfile");
- if(!(defined $newfh)){
- return 0;
- }
- my $lines = scalar @contents;
- for (my $i =0; $i < $lines; $i++) {
- print $newfh ($contents[$i]);
- }
-
- $oldfh->close;
- $newfh->close;
-
- chmod(0660, $newfile);
-
- return 1;
-
- } else {
- return 0;
+ if (! copy($oldfile,$newfile)) {
+ return 0;
}
+ chmod(0660, $newfile);
+ return 1;
}
#
# Host files are passed out with externally visible host IPs.
@@ -1013,7 +1019,7 @@ sub tie_user_hash {
$how, 0640)) {
# If this is a namespace for which a history is kept,
# make the history log entry:
- if (($namespace =~/^nohist\_/) && (defined($loghead))) {
+ if (($namespace !~/^nohist\_/) && (defined($loghead))) {
my $args = scalar @_;
Debug(" Opening history: $namespace $args");
my $hfh = IO::File->new(">>$proname/$namespace.hist");
@@ -1030,6 +1036,50 @@ sub tie_user_hash {
}
+# read_profile
+#
+# Returns a set of specific entries from a user's profile file.
+# this is a utility function that is used by both get_profile_entry and
+# get_profile_entry_encrypted.
+#
+# Parameters:
+# udom - Domain in which the user exists.
+# uname - User's account name (loncapa account)
+# namespace - The profile namespace to open.
+# what - A set of & separated queries.
+# Returns:
+# If all ok: - The string that needs to be shipped back to the user.
+# If failure - A string that starts with error: followed by the failure
+# reason.. note that this probabyl gets shipped back to the
+# user as well.
+#
+sub read_profile {
+ my ($udom, $uname, $namespace, $what) = @_;
+
+ my $hashref = &tie_user_hash($udom, $uname, $namespace,
+ &GDBM_READER());
+ if ($hashref) {
+ my @queries=split(/\&/,$what);
+ my $qresult='';
+
+ for (my $i=0;$i<=$#queries;$i++) {
+ $qresult.="$hashref->{$queries[$i]}&"; # Presumably failure gives empty string.
+ }
+ $qresult=~s/\&$//; # Remove trailing & from last lookup.
+ if (untie %$hashref) {
+ return $qresult;
+ } else {
+ return "error: ".($!+0)." untie (GDBM) Failed";
+ }
+ } else {
+ if ($!+0 == 2) {
+ return "error:No such file or GDBM reported bad block error";
+ } else {
+ return "error: ".($!+0)." tie (GDBM) Failed";
+ }
+ }
+
+}
#--------------------- Request Handlers --------------------------------------------
#
# By convention each request handler registers itself prior to the sub
@@ -1051,7 +1101,6 @@ sub tie_user_hash {
# 0 - Program should exit.
# Side effects:
# Reply information is sent to the client.
-
sub ping_handler {
my ($cmd, $tail, $client) = @_;
Debug("$cmd $tail $client .. $currenthostid:");
@@ -1079,7 +1128,6 @@ sub ping_handler {
# 0 - Program should exit.
# Side effects:
# Reply information is sent to the client.
-
sub pong_handler {
my ($cmd, $tail, $replyfd) = @_;
@@ -1134,7 +1182,6 @@ sub establish_key_handler {
}
®ister_handler("ekey", \&establish_key_handler, 0, 1,1);
-
# Handler for the load command. Returns the current system load average
# to the requestor.
#
@@ -1169,7 +1216,7 @@ sub load_handler {
return 1;
}
-register_handler("load", \&load_handler, 0, 1, 0);
+®ister_handler("load", \&load_handler, 0, 1, 0);
#
# Process the userload request. This sub returns to the client the current
@@ -1199,7 +1246,7 @@ sub user_load_handler {
return 1;
}
-register_handler("userload", \&user_load_handler, 0, 1, 0);
+®ister_handler("userload", \&user_load_handler, 0, 1, 0);
# Process a request for the authorization type of a user:
# (userauth).
@@ -1235,8 +1282,10 @@ sub user_authorization_type {
my ($type,$otherinfo) = split(/:/,$result);
if($type =~ /^krb/) {
$type = $result;
- }
- &Reply( $replyfd, "$type:\n", $userinput);
+ } else {
+ $type .= ':';
+ }
+ &Reply( $replyfd, "$type\n", $userinput);
}
return 1;
@@ -1256,7 +1305,6 @@ sub user_authorization_type {
# 0 - Program should exit
# Implicit Output:
# a reply is written to the client.
-
sub push_file_handler {
my ($cmd, $tail, $client) = @_;
@@ -1299,21 +1347,42 @@ sub push_file_handler {
# Side Effects:
# The reply is written to $client.
#
-
sub du_handler {
my ($cmd, $ududir, $client) = @_;
+ my ($ududir) = split(/:/,$ududir); # Make 'telnet' testing easier.
+ my $userinput = "$cmd:$ududir";
+
if ($ududir=~/\.\./ || $ududir!~m|^/home/httpd/|) {
&Failure($client,"refused\n","$cmd:$ududir");
return 1;
}
- my $duout = `du -ks $ududir 2>/dev/null`;
- $duout=~s/[^\d]//g; #preserve only the numbers
- &Reply($client,"$duout\n","$cmd:$ududir");
+ # Since $ududir could have some nasties in it,
+ # we will require that ududir is a valid
+ # directory. Just in case someone tries to
+ # slip us a line like .;(cd /home/httpd rm -rf*)
+ # etc.
+ #
+ if (-d $ududir) {
+ # And as Shakespeare would say to make
+ # assurance double sure,
+ # use execute_command to ensure that the command is not executed in
+ # a shell that can screw us up.
+
+ my $duout = execute_command("du -ks $ududir");
+ $duout=~s/[^\d]//g; #preserve only the numbers
+ &Reply($client,"$duout\n","$cmd:$ududir");
+ } else {
+
+ &Failure($client, "bad_directory:$ududir\n","$cmd:$ududir");
+
+ }
return 1;
}
®ister_handler("du", \&du_handler, 0, 1, 0);
-
+#
+# The ls_handler routine should be considered obosolete and is retained
+# for communication with legacy servers. Please see the ls2_handler.
#
# ls - list the contents of a directory. For each file in the
# selected directory the filename followed by the full output of
@@ -1331,6 +1400,7 @@ sub du_handler {
# The reply is written to $client.
#
sub ls_handler {
+ # obsoleted by ls2_handler
my ($cmd, $ulsdir, $client) = @_;
my $userinput = "$cmd:$ulsdir";
@@ -1370,15 +1440,78 @@ sub ls_handler {
$ulsout='no_such_dir';
}
if ($ulsout eq '') { $ulsout='empty'; }
- print $client "$ulsout\n";
+ &Reply($client, "$ulsout\n", $userinput); # This supports debug logging.
return 1;
}
®ister_handler("ls", \&ls_handler, 0, 1, 0);
+#
+# Please also see the ls_handler, which this routine obosolets.
+# ls2_handler differs from ls_handler in that it escapes its return
+# values before concatenating them together with ':'s.
+#
+# ls2 - list the contents of a directory. For each file in the
+# selected directory the filename followed by the full output of
+# the stat function is returned. The returned info for each
+# file are separated by ':'. The stat fields are separated by &'s.
+# Parameters:
+# $cmd - The command that dispatched us (ls).
+# $ulsdir - The directory path to list... I'm not sure what this
+# is relative as things like ls:. return e.g.
+# no_such_dir.
+# $client - Socket open on the client.
+# Returns:
+# 1 - indicating that the daemon should not disconnect.
+# Side Effects:
+# The reply is written to $client.
+#
+sub ls2_handler {
+ my ($cmd, $ulsdir, $client) = @_;
+ my $userinput = "$cmd:$ulsdir";
+ my $obs;
+ my $rights;
+ my $ulsout='';
+ my $ulsfn;
+ if (-e $ulsdir) {
+ if(-d $ulsdir) {
+ if (opendir(LSDIR,$ulsdir)) {
+ while ($ulsfn=readdir(LSDIR)) {
+ undef $obs, $rights;
+ my @ulsstats=stat($ulsdir.'/'.$ulsfn);
+ #We do some obsolete checking here
+ if(-e $ulsdir.'/'.$ulsfn.".meta") {
+ open(FILE, $ulsdir.'/'.$ulsfn.".meta");
+ my @obsolete=;
+ foreach my $obsolete (@obsolete) {
+ if($obsolete =~ m|()(on)|) { $obs = 1; }
+ if($obsolete =~ m|()(default)|) {
+ $rights = 1;
+ }
+ }
+ }
+ my $tmp = $ulsfn.'&'.join('&',@ulsstats);
+ if ($obs eq '1') { $tmp.="&1"; } else { $tmp.="&0"; }
+ if ($rights eq '1') { $tmp.="&1"; } else { $tmp.="&0"; }
+ $ulsout.= &escape($tmp).':';
+ }
+ closedir(LSDIR);
+ }
+ } else {
+ my @ulsstats=stat($ulsdir);
+ $ulsout.=$ulsfn.'&'.join('&',@ulsstats).':';
+ }
+ } else {
+ $ulsout='no_such_dir';
+ }
+ if ($ulsout eq '') { $ulsout='empty'; }
+ &Reply($client, "$ulsout\n", $userinput); # This supports debug logging.
+ return 1;
+}
+®ister_handler("ls2", \&ls2_handler, 0, 1, 0);
# Process a reinit request. Reinit requests that either
# lonc or lond be reinitialized so that an updated
@@ -1409,7 +1542,6 @@ sub reinit_process_handler {
}
return 1;
}
-
®ister_handler("reinit", \&reinit_process_handler, 1, 0, 1);
# Process the editing script for a table edit operation.
@@ -1451,8 +1583,7 @@ sub edit_table_handler {
}
return 1;
}
-register_handler("edit", \&edit_table_handler, 1, 0, 1);
-
+®ister_handler("edit", \&edit_table_handler, 1, 0, 1);
#
# Authenticate a user against the LonCAPA authentication
@@ -1507,8 +1638,7 @@ sub authenticate_handler {
return 1;
}
-
-register_handler("auth", \&authenticate_handler, 1, 1, 0);
+®ister_handler("auth", \&authenticate_handler, 1, 1, 0);
#
# Change a user's password. Note that this function is complicated by
@@ -1599,8 +1729,7 @@ sub change_password_handler {
return 1;
}
-register_handler("passwd", \&change_password_handler, 1, 1, 0);
-
+®ister_handler("passwd", \&change_password_handler, 1, 1, 0);
#
# Create a new user. User in this case means a lon-capa user.
@@ -1639,18 +1768,10 @@ sub add_user_handler {
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";
- }
- }
+ if (!&mkpath($passfilename)) {
+ $fperror="error: ".($!+0)." mkdir failed while attempting "
+ ."makeuser";
}
unless ($fperror) {
my $result=&make_passwd_file($uname, $umode,$npass, $passfilename);
@@ -1707,12 +1828,29 @@ sub change_authentication_handler {
chomp($npass);
$npass=&unescape($npass);
+ my $oldauth = &get_auth_type($udom, $uname); # Get old auth info.
my $passfilename = &password_path($udom, $uname);
if ($passfilename) { # Not allowed to create a new user!!
my $result=&make_passwd_file($uname, $umode,$npass,$passfilename);
+ #
+ # If the current auth mode is internal, and the old auth mode was
+ # unix, or krb*, and the user is an author for this domain,
+ # re-run manage_permissions for that role in order to be able
+ # to take ownership of the construction space back to www:www
+ #
+
+ if( (($oldauth =~ /^unix/) && ($umode eq "internal")) ||
+ (($oldauth =~ /^internal/) && ($umode eq "unix")) ) {
+ if(&is_author($udom, $uname)) {
+ &Debug(" Need to manage author permissions...");
+ &manage_permissions("/$udom/_au", $udom, $uname, "$umode:");
+ }
+ }
+
+
&Reply($client, $result, $userinput);
} else {
- &Failure($client, "non_authorized", $userinput); # Fail the user now.
+ &Failure($client, "non_authorized\n", $userinput); # Fail the user now.
}
}
return 1;
@@ -1865,21 +2003,10 @@ sub fetch_user_file_handler {
# Note that any regular files in the way of this path are
# wiped out to deal with some earlier folly of mine.
- my $path = $udir;
- if ($ufile =~m|(.+)/([^/]+)$|) {
- my @parts=split('/',$1);
- foreach my $part (@parts) {
- $path .= '/'.$part;
- if( -f $path) {
- unlink($path);
- }
- if ((-e $path)!=1) {
- mkdir($path,0770);
- }
- }
+ if (!&mkpath($udir.'/'.$ufile)) {
+ &Failure($client, "unable_to_create\n", $userinput);
}
-
my $destname=$udir.'/'.$ufile;
my $transname=$udir.'/'.$ufile.'.in.transit';
my $remoteurl='http://'.$clientip.'/userfiles/'.$fname;
@@ -1923,7 +2050,6 @@ sub fetch_user_file_handler {
#
# Returns:
# 1 - Continue processing.
-
sub remove_user_file_handler {
my ($cmd, $tail, $client) = @_;
@@ -1939,12 +2065,19 @@ sub remove_user_file_handler {
if (-e $udir) {
my $file=$udir.'/userfiles/'.$ufile;
if (-e $file) {
+ #
+ # If the file is a regular file unlink is fine...
+ # However it's possible the client wants a dir.
+ # removed, in which case rmdir is more approprate:
+ #
if (-f $file){
unlink($file);
} elsif(-d $file) {
rmdir($file);
}
if (-e $file) {
+ # File is still there after we deleted it ?!?
+
&Failure($client, "failed\n", "$cmd:$tail");
} else {
&Reply($client, "ok\n", "$cmd:$tail");
@@ -1969,7 +2102,6 @@ sub remove_user_file_handler {
#
# Returns:
# 1 - Continue processing.
-
sub mkdir_user_file_handler {
my ($cmd, $tail, $client) = @_;
@@ -1983,17 +2115,11 @@ sub mkdir_user_file_handler {
} else {
my $udir = &propath($udom,$uname);
if (-e $udir) {
- my $newdir=$udir.'/userfiles/'.$ufile;
- if (!-e $newdir) {
- mkdir($newdir);
- if (!-e $newdir) {
- &Failure($client, "failed\n", "$cmd:$tail");
- } else {
- &Reply($client, "ok\n", "$cmd:$tail");
- }
- } else {
- &Failure($client, "not_found\n", "$cmd:$tail");
+ my $newdir=$udir.'/userfiles/'.$ufile.'/';
+ if (!&mkpath($newdir)) {
+ &Failure($client, "failed\n", "$cmd:$tail");
}
+ &Reply($client, "ok\n", "$cmd:$tail");
} else {
&Failure($client, "not_home\n", "$cmd:$tail");
}
@@ -2011,7 +2137,6 @@ sub mkdir_user_file_handler {
#
# Returns:
# 1 - Continue processing.
-
sub rename_user_file_handler {
my ($cmd, $tail, $client) = @_;
@@ -2045,10 +2170,9 @@ sub rename_user_file_handler {
}
®ister_handler("renameuserfile", \&rename_user_file_handler, 0,1,0);
-
#
-# Authenticate access to a user file by checking the user's
-# session token(?)
+# Authenticate access to a user file by checking that the token the user's
+# passed also exists in their session file
#
# Parameters:
# cmd - The request keyword that dispatched to tus.
@@ -2056,31 +2180,28 @@ sub rename_user_file_handler {
# 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';
+ my $reply="non_auth\n";
if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'.
$session.'.id')) {
while (my $line=) {
- if ($line=~ m|userfile\.\Q$fname\E\=|) { $reply='ok'; }
+ if ($line=~ m|userfile\.\Q$fname\E\=|) { $reply="ok\n"; }
}
close(ENVIN);
- &Reply($client, $reply);
+ &Reply($client, $reply, "$cmd:$tail");
} 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.
#
@@ -2109,6 +2230,7 @@ sub unsubscribe_handler {
return 1;
}
®ister_handler("unsub", \&unsubscribe_handler, 0, 1, 0);
+
# Subscribe to a resource
#
# Parameters:
@@ -2187,7 +2309,7 @@ sub activity_log_handler {
return 1;
}
-register_handler("log", \&activity_log_handler, 0, 1, 0);
+®ister_handler("log", \&activity_log_handler, 0, 1, 0);
#
# Put a namespace entry in a user profile hash.
@@ -2238,6 +2360,61 @@ sub put_user_profile_entry {
}
®ister_handler("put", \&put_user_profile_entry, 0, 1, 0);
+# Put a piece of new data in hash, returns error if entry already 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.
+#
+sub newput_user_profile_entry {
+ my ($cmd, $tail, $client) = @_;
+
+ my $userinput = "$cmd:$tail";
+
+ my ($udom,$uname,$namespace,$what) =split(/:/,$tail,4);
+ if ($namespace eq 'roles') {
+ &Failure( $client, "refused\n", $userinput);
+ return 1;
+ }
+
+ chomp($what);
+
+ my $hashref = &tie_user_hash($udom, $uname, $namespace,
+ &GDBM_WRCREAT(),"N",$what);
+ if(!$hashref) {
+ &Failure( $client, "error: ".($!)." tie(GDBM) Failed ".
+ "while attempting put\n", $userinput);
+ return 1;
+ }
+
+ my @pairs=split(/\&/,$what);
+ foreach my $pair (@pairs) {
+ my ($key,$value)=split(/=/,$pair);
+ if (exists($hashref->{$key})) {
+ &Failure($client, "key_exists: ".$key."\n",$userinput);
+ return 1;
+ }
+ }
+
+ 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);
+ }
+ return 1;
+}
+®ister_handler("newput", \&newput_user_profile_entry, 0, 1, 0);
+
#
# Increment a profile entry in the user history file.
# The history contains keyword value pairs. In this case,
@@ -2268,11 +2445,17 @@ sub increment_user_value_handler {
my @pairs=split(/\&/,$what);
foreach my $pair (@pairs) {
my ($key,$value)=split(/=/,$pair);
+ $value = &unescape($value);
# We could check that we have a number...
if (! defined($value) || $value eq '') {
$value = 1;
}
$hashref->{$key}+=$value;
+ if ($namespace eq 'nohist_resourcetracker') {
+ if ($hashref->{$key} < 0) {
+ $hashref->{$key} = 0;
+ }
+ }
}
if (untie(%$hashref)) {
&Reply( $client, "ok\n", $userinput);
@@ -2292,7 +2475,6 @@ sub increment_user_value_handler {
}
®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
@@ -2332,11 +2514,14 @@ sub roles_put_handler {
# is done on close this improves the chances the log will be an un-
# corrupted ordered thing.
if ($hashref) {
+ my $pass_entry = &get_auth_type($udom, $uname);
+ my ($auth_type,$pwd) = split(/:/, $pass_entry);
+ $auth_type = $auth_type.":";
my @pairs=split(/\&/,$what);
foreach my $pair (@pairs) {
my ($key,$value)=split(/=/,$pair);
&manage_permissions($key, $udom, $uname,
- &get_auth_type( $udom, $uname));
+ $auth_type);
$hashref->{$key}=$value;
}
if (untie($hashref)) {
@@ -2431,32 +2616,17 @@ sub get_profile_entry {
my ($udom,$uname,$namespace,$what) = split(/:/,$tail);
chomp($what);
- my $hashref = &tie_user_hash($udom, $uname, $namespace,
- &GDBM_READER());
- if ($hashref) {
- my @queries=split(/\&/,$what);
- my $qresult='';
-
- for (my $i=0;$i<=$#queries;$i++) {
- $qresult.="$hashref->{$queries[$i]}&"; # Presumably failure gives empty string.
- }
- $qresult=~s/\&$//; # Remove trailing & from last lookup.
- if (untie(%$hashref)) {
- &Reply($client, "$qresult\n", $userinput);
- } else {
- &Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
- "while attempting get\n", $userinput);
- }
+
+ my $replystring = read_profile($udom, $uname, $namespace, $what);
+ my ($first) = split(/:/,$replystring);
+ if($first ne "error") {
+ &Reply($client, "$replystring\n", $userinput);
} else {
- if ($!+0 == 2) { # +0 coerces errno -> number 2 is ENOENT
- &Failure($client, "error:No such file or ".
- "GDBM reported bad block error\n", $userinput);
- } else { # Some other undifferentiated err.
- &Failure($client, "error: ".($!+0)." tie(GDBM) Failed ".
- "while attempting get\n", $userinput);
- }
+ &Failure($client, $replystring." while attempting get\n", $userinput);
}
return 1;
+
+
}
®ister_handler("get", \&get_profile_entry, 0,1,0);
@@ -2486,42 +2656,33 @@ sub get_profile_entry_encrypted {
my ($cmd,$udom,$uname,$namespace,$what) = split(/:/,$userinput);
chomp($what);
- my $hashref = &tie_user_hash($udom, $uname, $namespace,
- &GDBM_READER());
- if ($hashref) {
- my @queries=split(/\&/,$what);
- my $qresult='';
- for (my $i=0;$i<=$#queries;$i++) {
- $qresult.="$hashref->{$queries[$i]}&";
- }
- if (untie(%$hashref)) {
- $qresult=~s/\&$//;
- if ($cipher) {
- my $cmdlength=length($qresult);
- $qresult.=" ";
- my $encqresult='';
- for(my $encidx=0;$encidx<=$cmdlength;$encidx+=8) {
- $encqresult.= unpack("H16",
- $cipher->encrypt(substr($qresult,
- $encidx,
- 8)));
- }
- &Reply( $client, "enc:$cmdlength:$encqresult\n", $userinput);
- } else {
- &Failure( $client, "error:no_key\n", $userinput);
+ my $qresult = read_profile($udom, $uname, $namespace, $what);
+ my ($first) = split(/:/, $qresult);
+ if($first ne "error") {
+
+ if ($cipher) {
+ my $cmdlength=length($qresult);
+ $qresult.=" ";
+ my $encqresult='';
+ for(my $encidx=0;$encidx<=$cmdlength;$encidx+=8) {
+ $encqresult.= unpack("H16",
+ $cipher->encrypt(substr($qresult,
+ $encidx,
+ 8)));
}
+ &Reply( $client, "enc:$cmdlength:$encqresult\n", $userinput);
} else {
- &Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
- "while attempting eget\n", $userinput);
- }
+ &Failure( $client, "error:no_key\n", $userinput);
+ }
} else {
- &Failure($client, "error: ".($!+0)." tie(GDBM) Failed ".
- "while attempting eget\n", $userinput);
+ &Failure($client, "$qresult while attempting eget\n", $userinput);
+
}
return 1;
}
-®ister_handler("eget", \&GetProfileEntryEncrypted, 0, 1, 0);
+®ister_handler("eget", \&get_profile_entry_encrypted, 0, 1, 0);
+
#
# Deletes a key in a user profile database.
#
@@ -2540,7 +2701,6 @@ sub get_profile_entry_encrypted {
# 0 - Exit server.
#
#
-
sub delete_profile_entry {
my ($cmd, $tail, $client) = @_;
@@ -2569,6 +2729,7 @@ sub delete_profile_entry {
return 1;
}
®ister_handler("del", \&delete_profile_entry, 0, 1, 0);
+
#
# List the set of keys that are defined in a profile database file.
# A successful reply from this will contain an & separated list of
@@ -2747,7 +2908,6 @@ sub dump_with_regexp {
return 1;
}
-
®ister_handler("dump", \&dump_with_regexp, 0, 1, 0);
# Store a set of key=value pairs associated with a versioned name.
@@ -2779,7 +2939,7 @@ sub store_handler {
chomp($what);
my @pairs=split(/\&/,$what);
my $hashref = &tie_user_hash($udom, $uname, $namespace,
- &GDBM_WRCREAT(), "P",
+ &GDBM_WRCREAT(), "S",
"$rid:$what");
if ($hashref) {
my $now = time;
@@ -2813,6 +2973,7 @@ sub store_handler {
return 1;
}
®ister_handler("store", \&store_handler, 0, 1, 0);
+
#
# Dump out all versions of a resource that has key=value pairs associated
# with it for each version. These resources are built up via the store
@@ -2913,6 +3074,7 @@ sub send_chat_handler {
return 1;
}
®ister_handler("chatsend", \&send_chat_handler, 0, 1, 0);
+
#
# Retrieve the set of chat messagss from a discussion board.
#
@@ -3048,6 +3210,14 @@ sub reply_query_handler {
# $tail - Tail of the command. In this case consists of a colon
# separated list contaning the domain to apply this to and
# an ampersand separated list of keyword=value pairs.
+# Each value is a colon separated list that includes:
+# description, institutional code and course owner.
+# For backward compatibility with versions included
+# in LON-CAPA 1.1.X (and earlier) and 1.2.X, institutional
+# code and/or course owner are preserved from the existing
+# record when writing a new record in response to 1.1 or
+# 1.2 implementations of lonnet::flushcourselogs().
+#
# $client - Socket open on the client.
# Returns:
# 1 - indicating that processing should continue
@@ -3061,7 +3231,7 @@ sub put_course_id_handler {
my $userinput = "$cmd:$tail";
- my ($udom, $what) = split(/:/, $tail);
+ my ($udom, $what) = split(/:/, $tail,2);
chomp($what);
my $now=time;
my @pairs=split(/\&/,$what);
@@ -3069,21 +3239,38 @@ sub put_course_id_handler {
my $hashref = &tie_domain_hash($udom, "nohist_courseids", &GDBM_WRCREAT());
if ($hashref) {
foreach my $pair (@pairs) {
- my ($key,$value)=split(/=/,$pair);
- $hashref->{$key}=$value.':'.$now;
+ my ($key,$courseinfo) = split(/=/,$pair,2);
+ $courseinfo =~ s/=/:/g;
+
+ my @current_items = split(/:/,$hashref->{$key});
+ shift(@current_items); # remove description
+ pop(@current_items); # remove last access
+ my $numcurrent = scalar(@current_items);
+
+ my @new_items = split(/:/,$courseinfo);
+ my $numnew = scalar(@new_items);
+ if ($numcurrent > 0) {
+ if ($numnew == 1) { # flushcourselogs() from 1.1 or earlier
+ $courseinfo .= ':'.join(':',@current_items);
+ } elsif ($numnew == 2) { # flushcourselogs() from 1.2.X
+ $courseinfo .= ':'.$current_items[$numcurrent-1];
+ }
+ }
+ $hashref->{$key}=$courseinfo.':'.$now;
}
if (untie(%$hashref)) {
- &Reply($client, "ok\n", $userinput);
+ &Reply( $client, "ok\n", $userinput);
} else {
- &Failure( $client, "error: ".($!+0)
+ &Failure($client, "error: ".($!+0)
." untie(GDBM) Failed ".
"while attempting courseidput\n", $userinput);
}
} else {
- &Failure( $client, "error: ".($!+0)
+ &Failure($client, "error: ".($!+0)
." tie(GDBM) Failed ".
"while attempting courseidput\n", $userinput);
}
+
return 1;
}
@@ -3107,6 +3294,15 @@ sub put_course_id_handler {
# description - regular expression that is used to filter
# the dump. Only keywords matching this regexp
# will be used.
+# institutional code - optional supplied code to filter
+# the dump. Only courses with an institutional code
+# that match the supplied code will be returned.
+# owner - optional supplied username of owner to filter
+# the dump. Only courses for which the course
+# owner matches the supplied username will be
+# returned. Implicit assumption that owner
+# is a user in the domain in which the
+# course database is defined.
# $client - The socket open on the client.
# Returns:
# 1 - Continue processing.
@@ -3117,32 +3313,66 @@ sub dump_course_id_handler {
my $userinput = "$cmd:$tail";
- my ($udom,$since,$description) =split(/:/,$tail);
+ my ($udom,$since,$description,$instcodefilter,$ownerfilter,$coursefilter) =split(/:/,$tail);
if (defined($description)) {
$description=&unescape($description);
} else {
$description='.';
}
+ if (defined($instcodefilter)) {
+ $instcodefilter=&unescape($instcodefilter);
+ } else {
+ $instcodefilter='.';
+ }
+ if (defined($ownerfilter)) {
+ $ownerfilter=&unescape($ownerfilter);
+ } else {
+ $ownerfilter='.';
+ }
+ if (defined($coursefilter)) {
+ $coursefilter=&unescape($coursefilter);
+ } else {
+ $coursefilter='.';
+ }
+
unless (defined($since)) { $since=0; }
my $qresult='';
my $hashref = &tie_domain_hash($udom, "nohist_courseids", &GDBM_WRCREAT());
if ($hashref) {
while (my ($key,$value) = each(%$hashref)) {
- my ($descr,$lasttime,$inst_code);
- if ($value =~ m/^([^\:]*):([^\:]*):(\d+)$/) {
- ($descr,$inst_code,$lasttime)=($1,$2,$3);
- } else {
- ($descr,$lasttime) = split(/\:/,$value);
- }
+ my ($descr,$lasttime,$inst_code,$owner);
+ my @courseitems = split(/:/,$value);
+ $lasttime = pop(@courseitems);
+ ($descr,$inst_code,$owner)=@courseitems;
if ($lasttime<$since) { next; }
- if ($description eq '.') {
- $qresult.=$key.'='.$descr.':'.$inst_code.'&';
- } else {
- my $unescapeVal = &unescape($descr);
- if (eval('$unescapeVal=~/\Q$description\E/i')) {
- $qresult.=$key.'='.$descr.':'.$inst_code.'&';
+ my $match = 1;
+ unless ($description eq '.') {
+ my $unescapeDescr = &unescape($descr);
+ unless (eval('$unescapeDescr=~/\Q$description\E/i')) {
+ $match = 0;
}
+ }
+ unless ($instcodefilter eq '.' || !defined($instcodefilter)) {
+ my $unescapeInstcode = &unescape($inst_code);
+ unless (eval('$unescapeInstcode=~/\Q$instcodefilter\E/i')) {
+ $match = 0;
+ }
}
+ unless ($ownerfilter eq '.' || !defined($ownerfilter)) {
+ my $unescapeOwner = &unescape($owner);
+ unless (eval('$unescapeOwner=~/\Q$ownerfilter\E/i')) {
+ $match = 0;
+ }
+ }
+ unless ($coursefilter eq '.' || !defined($coursefilter)) {
+ my $unescapeCourse = &unescape($key);
+ unless (eval('$unescapeCourse=~/^$udom(_)\Q$coursefilter\E$/')) {
+ $match = 0;
+ }
+ }
+ if ($match == 1) {
+ $qresult.=$key.'='.$descr.':'.$inst_code.':'.$owner.'&';
+ }
}
if (untie(%$hashref)) {
chop($qresult);
@@ -3206,8 +3436,8 @@ sub put_id_handler {
return 1;
}
-
®ister_handler("idput", \&put_id_handler, 0, 1, 0);
+
#
# Retrieves a set of id values from the id database.
# Returns an & separated list of results, one for each requested id to the
@@ -3256,8 +3486,7 @@ sub get_id_handler {
return 1;
}
-
-register_handler("idget", \&get_id_handler, 0, 1, 0);
+®ister_handler("idget", \&get_id_handler, 0, 1, 0);
#
# Process the tmpput command I'm not sure what this does.. Seems to
@@ -3300,6 +3529,7 @@ sub tmp_put_handler {
}
®ister_handler("tmpput", \&tmp_put_handler, 0, 1, 0);
+
# Processes the tmpget command. This command returns the contents
# of a temporary resource file(?) created via tmpput.
#
@@ -3312,7 +3542,6 @@ sub tmp_put_handler {
# 1 - Inidcating processing can continue.
# Side effects:
# A reply is sent to the client.
-
#
sub tmp_get_handler {
my ($cmd, $id, $client) = @_;
@@ -3335,6 +3564,7 @@ sub tmp_get_handler {
return 1;
}
®ister_handler("tmpget", \&tmp_get_handler, 0, 1, 0);
+
#
# Process the tmpdel command. This command deletes a temp resource
# created by the tmpput command.
@@ -3368,6 +3598,7 @@ sub tmp_del_handler {
}
®ister_handler("tmpdel", \&tmp_del_handler, 0, 1, 0);
+
#
# Processes the setannounce command. This command
# creates a file named announce.txt in the top directory of
@@ -3406,6 +3637,7 @@ sub set_announce_handler {
return 1;
}
®ister_handler("setannounce", \&set_announce_handler, 0, 1, 0);
+
#
# Return the version of the daemon. This can be used to determine
# the compatibility of cross version installations or, alternatively to
@@ -3430,6 +3662,7 @@ sub get_version_handler {
return 1;
}
®ister_handler("version", \&get_version_handler, 0, 1, 0);
+
# Set the current host and domain. This is used to support
# multihomed systems. Each IP of the system, or even separate daemons
# on the same IP can be treated as handling a separate lonCAPA virtual
@@ -3566,6 +3799,7 @@ sub validate_course_owner_handler {
return 1;
}
®ister_handler("autonewcourse", \&validate_course_owner_handler, 0, 1, 0);
+
#
# Validate a course section in the official schedule of classes
# from the institutions point of view (part of autoenrollment).
@@ -3646,7 +3880,6 @@ sub create_auto_enroll_password_handler
#
# Returns:
# 1 - Continue processing.
-
sub retrieve_auto_file_handler {
my ($cmd, $tail, $client) = @_;
my $userinput = "cmd:$tail";
@@ -3731,20 +3964,67 @@ sub get_institutional_code_format_handle
return 1;
}
+®ister_handler("autoinstcodeformat",
+ \&get_institutional_code_format_handler,0,1,0);
-®ister_handler("autoinstcodeformat", \&get_institutional_code_format_handler,
- 0,1,0);
-
-#
-#
-#
-#
#
+# Gets a student's photo to exist (in the correct image type) in the user's
+# directory.
+# Formal Parameters:
+# $cmd - The command request that got us dispatched.
+# $tail - A colon separated set of words that will be split into:
+# $domain - student's domain
+# $uname - student username
+# $type - image type desired
+# $client - The socket open on the client.
+# Returns:
+# 1 - continue processing.
+sub student_photo_handler {
+ my ($cmd, $tail, $client) = @_;
+ my ($domain,$uname,$type) = split(/:/, $tail);
+
+ my $path=&propath($domain,$uname).
+ '/userfiles/internal/studentphoto.'.$type;
+ if (-e $path) {
+ &Reply($client,"ok\n","$cmd:$tail");
+ return 1;
+ }
+ &mkpath($path);
+ my $file=&localstudentphoto::fetch($domain,$uname);
+ if (!$file) {
+ &Failure($client,"unavailable\n","$cmd:$tail");
+ return 1;
+ }
+ if (!-e $path) { &convert_photo($file,$path); }
+ if (-e $path) {
+ &Reply($client,"ok\n","$cmd:$tail");
+ return 1;
+ }
+ &Failure($client,"unable_to_convert\n","$cmd:$tail");
+ return 1;
+}
+®ister_handler("studentphoto", \&student_photo_handler, 0, 1, 0);
+
+# mkpath makes all directories for a file, expects an absolute path with a
+# file or a trailing / if just a dir is passed
+# returns 1 on success 0 on failure
+sub mkpath {
+ my ($file)=@_;
+ my @parts=split(/\//,$file,-1);
+ my $now=$parts[0].'/'.$parts[1].'/'.$parts[2];
+ for (my $i=3;$i<= ($#parts-1);$i++) {
+ $now.='/'.$parts[$i];
+ if (!-e $now) {
+ if (!mkdir($now,0770)) { return 0; }
+ }
+ }
+ return 1;
+}
+
#---------------------------------------------------------------
#
# Getting, decoding and dispatching requests:
#
-
#
# Get a Request:
# Gets a Request message from the client. The transaction
@@ -3781,7 +4061,7 @@ sub process_request {
$userinput = decipher($userinput);
$wasenc=1;
if(!$userinput) { # Cipher not defined.
- &Failure($client, "error: Encrypted data without negotated key");
+ &Failure($client, "error: Encrypted data without negotated key\n");
return 0;
}
}
@@ -3851,114 +4131,7 @@ sub process_request {
}
-#------------------- Commands not yet in spearate handlers. --------------
-
-#------------------------------- is auto-enrollment enabled?
- if ($userinput =~/^autorun/) {
- if (isClient) {
- my ($cmd,$cdom) = split(/:/,$userinput);
- my $outcome = &localenroll::run($cdom);
- print $client "$outcome\n";
- } else {
- print $client "0\n";
- }
-#------------------------------- get official sections (for auto-enrollment).
- } elsif ($userinput =~/^autogetsections/) {
- if (isClient) {
- my ($cmd,$coursecode,$cdom)=split(/:/,$userinput);
- my @secs = &localenroll::get_sections($coursecode,$cdom);
- my $seclist = &escape(join(':',@secs));
- print $client "$seclist\n";
- } else {
- print $client "refused\n";
- }
-#----------------------- validate owner of new course section (for auto-enrollment).
- } elsif ($userinput =~/^autonewcourse/) {
- if (isClient) {
- my ($cmd,$inst_course_id,$owner,$cdom)=split(/:/,$userinput);
- my $outcome = &localenroll::new_course($inst_course_id,$owner,$cdom);
- print $client "$outcome\n";
- } else {
- print $client "refused\n";
- }
-#-------------- validate course section in schedule of classes (for auto-enrollment).
- } elsif ($userinput =~/^autovalidatecourse/) {
- if (isClient) {
- my ($cmd,$inst_course_id,$cdom)=split(/:/,$userinput);
- my $outcome=&localenroll::validate_courseID($inst_course_id,$cdom);
- print $client "$outcome\n";
- } else {
- print $client "refused\n";
- }
-#--------------------------- create password for new user (for auto-enrollment).
- } elsif ($userinput =~/^autocreatepassword/) {
- if (isClient) {
- my ($cmd,$authparam,$cdom)=split(/:/,$userinput);
- my ($create_passwd,$authchk);
- ($authparam,$create_passwd,$authchk) = &localenroll::create_password($authparam,$cdom);
- print $client &escape($authparam.':'.$create_passwd.':'.$authchk)."\n";
- } else {
- print $client "refused\n";
- }
-#--------------------------- read and remove temporary files (for auto-enrollment).
- } elsif ($userinput =~/^autoretrieve/) {
- if (isClient) {
- my ($cmd,$filename) = split(/:/,$userinput);
- my $source = $perlvar{'lonDaemons'}.'/tmp/'.$filename;
- if ( (-e $source) && ($filename ne '') ) {
- my $reply = '';
- if (open(my $fh,$source)) {
- while (<$fh>) {
- chomp($_);
- $_ =~ s/^\s+//g;
- $_ =~ s/\s+$//g;
- $reply .= $_;
- }
- close($fh);
- print $client &escape($reply)."\n";
-# unlink($source);
- } else {
- print $client "error\n";
- }
- } else {
- print $client "error\n";
- }
- } else {
- print $client "refused\n";
- }
-#--------------------- read and retrieve institutional code format
-# (for support form).
- } elsif ($userinput =~/^autoinstcodeformat/) {
- if (isClient) {
- my $reply;
- my($cmd,$cdom,$course) = split(/:/,$userinput);
- my @pairs = split/\&/,$course;
- my %instcodes = ();
- my %codes = ();
- my @codetitles = ();
- my %cat_titles = ();
- my %cat_order = ();
- foreach (@pairs) {
- my ($key,$value) = split/=/,$_;
- $instcodes{&unescape($key)} = &unescape($value);
- }
- my $formatreply = &localenroll::instcode_format($cdom,\%instcodes,\%codes,\@codetitles,\%cat_titles,\%cat_order);
- if ($formatreply eq 'ok') {
- my $codes_str = &hash2str(%codes);
- my $codetitles_str = &array2str(@codetitles);
- my $cat_titles_str = &hash2str(%cat_titles);
- my $cat_order_str = &hash2str(%cat_order);
- print $client $codes_str.':'.$codetitles_str.':'.$cat_titles_str.':'.$cat_order_str."\n";
- }
- } else {
- print $client "refused\n";
- }
-# ------------------------------------------------------------- unknown command
-
- } else {
- # unknown command
- print $client "unknown_cmd\n";
- }
+ print $client "unknown_cmd\n";
# -------------------------------------------------------------------- complete
Debug("process_request - returning 1");
return 1;
@@ -4220,12 +4393,18 @@ sub ReadHostTable {
my $myloncapaname = $perlvar{'lonHostID'};
Debug("My loncapa name is : $myloncapaname");
while (my $configline=) {
- if (!($configline =~ /^\s*\#/)) {
- my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
- chomp($ip); $ip=~s/\D+$//;
+ if ($configline !~ /^\s*\#/ && $configline !~ /^\s*$/ ) {
+ my ($id,$domain,$role,$name)=split(/:/,$configline);
+ $name=~s/\s//g;
+ my $ip = gethostbyname($name);
+ if (length($ip) ne 4) {
+ &logthis("Skipping host $id name $name no IP $ip found\n");
+ next;
+ }
+ $ip=inet_ntoa($ip);
$hostid{$ip}=$id; # LonCAPA name of host by IP.
$hostdom{$id}=$domain; # LonCAPA domain name of host.
- $hostip{$id}=$ip; # IP address of host.
+ $hostip{$id}=$ip; # IP address of host.
$hostdns{$name} = $id; # LonCAPA name of host by DNS.
if ($id eq $perlvar{'lonHostID'}) {
@@ -4362,8 +4541,6 @@ sub Reply {
Debug("Request was $request Reply was $reply");
$Transactions++;
-
-
}
@@ -4406,7 +4583,7 @@ sub logstatus {
flock(LOG,LOCK_EX);
print LOG $$."\t".$clientname."\t".$currenthostid."\t"
.$status."\t".$lastlog."\t $keymode\n";
- flock(DB,LOCK_UN);
+ flock(LOG,LOCK_UN);
close(LOG);
}
&status("Finished logging");
@@ -4637,8 +4814,6 @@ sub make_new_child {
if (defined($iaddr)) {
$clientip = inet_ntoa($iaddr);
Debug("Connected with $clientip");
- $clientdns = gethostbyaddr($iaddr, AF_INET);
- Debug("Connected with $clientdns by name");
} else {
&logthis("Unable to determine clientip");
$clientip='Unavailable';
@@ -4678,18 +4853,23 @@ sub make_new_child {
ReadManagerTable; # May also be a manager!!
- my $clientrec=($hostid{$clientip} ne undef);
- my $ismanager=($managers{$clientip} ne undef);
+ my $outsideip=$clientip;
+ if ($clientip eq '127.0.0.1') {
+ $outsideip=$hostip{$perlvar{'lonHostID'}};
+ }
+
+ my $clientrec=($hostid{$outsideip} ne undef);
+ my $ismanager=($managers{$outsideip} ne undef);
$clientname = "[unknonwn]";
if($clientrec) { # Establish client type.
$ConnectionType = "client";
- $clientname = $hostid{$clientip};
+ $clientname = $hostid{$outsideip};
if($ismanager) {
$ConnectionType = "both";
}
} else {
$ConnectionType = "manager";
- $clientname = $managers{$clientip};
+ $clientname = $managers{$outsideip};
}
my $clientok;
@@ -4833,8 +5013,35 @@ sub make_new_child {
exit;
}
+#
+# Determine if a user is an author for the indicated domain.
+#
+# Parameters:
+# domain - domain to check in .
+# user - Name of user to check.
+#
+# Return:
+# 1 - User is an author for domain.
+# 0 - User is not an author for domain.
+sub is_author {
+ my ($domain, $user) = @_;
+ &Debug("is_author: $user @ $domain");
+ my $hashref = &tie_user_hash($domain, $user, "roles",
+ &GDBM_READER());
+
+ # Author role should show up as a key /domain/_au
+
+ my $key = "/$domain/_au";
+ my $value = $hashref->{$key};
+
+ if(defined($value)) {
+ &Debug("$user @ $domain is an author");
+ }
+
+ return defined($value);
+}
#
# Checks to see if the input roleput request was to set
# an author role. If so, invokes the lchtmldir script to set
@@ -4849,13 +5056,17 @@ sub make_new_child {
sub manage_permissions
{
+
my ($request, $domain, $user, $authtype) = @_;
+ &Debug("manage_permissions: $request $domain $user $authtype");
+
# See if the request is of the form /$domain/_au
if($request =~ /^(\/$domain\/_au)$/) { # It's an author rolesput...
my $execdir = $perlvar{'lonDaemons'};
my $userhome= "/home/$user" ;
&logthis("system $execdir/lchtmldir $userhome $user $authtype");
+ &Debug("Setting homedir permissions for $userhome");
system("$execdir/lchtmldir $userhome $user $authtype");
}
}
@@ -4871,12 +5082,7 @@ sub manage_permissions
#
sub password_path {
my ($domain, $user) = @_;
-
-
- my $path = &propath($domain, $user);
- $path .= "/passwd";
-
- return $path;
+ return &propath($domain, $user).'/passwd';
}
# Password Filename
@@ -4951,12 +5157,7 @@ sub get_auth_type
Debug("Password info = $realpassword\n");
my ($authtype, $contentpwd) = split(/:/, $realpassword);
Debug("Authtype = $authtype, content = $contentpwd\n");
- my $availinfo = '';
- if($authtype eq 'krb4' or $authtype eq 'krb5') {
- $availinfo = $contentpwd;
- }
-
- return "$authtype:$availinfo";
+ return "$authtype:$contentpwd";
} else {
Debug("Returning nouser");
return "nouser";
@@ -4989,7 +5190,8 @@ sub validate_user {
# At the end of this function. I'll ensure that it's not still that
# value so we don't just wind up returning some accidental value
# as a result of executing an unforseen code path that
- # did not set $validated.
+ # did not set $validated. At the end of valid execution paths,
+ # validated shoule be 1 for success or 0 for failuer.
my $validated = -3.14159;
@@ -5053,7 +5255,7 @@ sub validate_user {
my $krbserver = &Authen::Krb5::parse_name($krbservice);
my $credentials= &Authen::Krb5::cc_default();
$credentials->initialize($krbclient);
- my $krbreturn = &Authen::KRb5::get_in_tkt_with_password($krbclient,
+ my $krbreturn = &Authen::Krb5::get_in_tkt_with_password($krbclient,
$krbserver,
$password,
$credentials);
@@ -5077,7 +5279,11 @@ sub validate_user {
#
unless ($validated != -3.14159) {
- die "ValidateUser - failed to set the value of validated";
+ # I >really really< want to know if this happens.
+ # since it indicates that user authentication is badly
+ # broken in some code path.
+ #
+ die "ValidateUser - failed to set the value of validated $domain, $user $password";
}
return $validated;
}
@@ -5300,7 +5506,11 @@ sub make_passwd_file {
if ($umode eq 'krb4' or $umode eq 'krb5') {
{
my $pf = IO::File->new(">$passfilename");
- print $pf "$umode:$npass\n";
+ if ($pf) {
+ print $pf "$umode:$npass\n";
+ } else {
+ $result = "pass_file_failed_error";
+ }
}
} elsif ($umode eq 'internal') {
my $salt=time;
@@ -5309,12 +5519,20 @@ sub make_passwd_file {
{
&Debug("Creating internal auth");
my $pf = IO::File->new(">$passfilename");
- print $pf "internal:$ncpass\n";
+ if($pf) {
+ print $pf "internal:$ncpass\n";
+ } else {
+ $result = "pass_file_failed_error";
+ }
}
} elsif ($umode eq 'localauth') {
{
my $pf = IO::File->new(">$passfilename");
- print $pf "localauth:$npass\n";
+ if($pf) {
+ print $pf "localauth:$npass\n";
+ } else {
+ $result = "pass_file_failed_error";
+ }
}
} elsif ($umode eq 'unix') {
{
@@ -5353,13 +5571,21 @@ sub make_passwd_file {
$result = "lcuseradd_failed:$error_text\n";
} else {
my $pf = IO::File->new(">$passfilename");
- print $pf "unix:\n";
+ if($pf) {
+ print $pf "unix:\n";
+ } else {
+ $result = "pass_file_failed_error";
+ }
}
}
} elsif ($umode eq 'none') {
{
my $pf = IO::File->new("> $passfilename");
- print $pf "none:\n";
+ if($pf) {
+ print $pf "none:\n";
+ } else {
+ $result = "pass_file_failed_error";
+ }
}
} else {
$result="auth_mode_error\n";
@@ -5367,6 +5593,11 @@ sub make_passwd_file {
return $result;
}
+sub convert_photo {
+ my ($start,$dest)=@_;
+ system("convert $start $dest");
+}
+
sub sethost {
my ($remotereq) = @_;
my (undef,$hostid)=split(/:/,$remotereq);