--- loncom/lond 2004/02/24 11:22:41 1.178.2.3 +++ loncom/lond 2004/02/24 16:51:40 1.178.2.4 @@ -2,7 +2,7 @@ # The LearningOnline Network # lond "LON Daemon" Server (port "LOND" 5663) # -# $Id: lond,v 1.178.2.3 2004/02/24 11:22:41 foxr Exp $ +# $Id: lond,v 1.178.2.4 2004/02/24 16:51:40 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -53,7 +53,7 @@ my $DEBUG = 1; # Non zero to ena my $status=''; my $lastlog=''; -my $VERSION='$Revision: 1.178.2.3 $'; #' stupid emacs +my $VERSION='$Revision: 1.178.2.4 $'; #' stupid emacs my $remoteVERSION; my $currenthostid; my $currentdomainid; @@ -189,21 +189,20 @@ sub GetRequest { # cipher - This global holds the negotiated encryption key. # sub Decipher { - my $input = shift; - my $output = ''; + my $input = shift; + my $output = ''; - if($cipher) { - my($enc, $enclength, $encinput) = split(/:/, $input); - for(my $encidx = 0; $encidx < length($encinput); $encidx += 16) { - $output .= - $cipher->decrypt(pack("H16", substr($encinput, $encidx, 16))); - } - return substr($output, 0, $enclength); - } else { - return undef; - } - + if($cipher) { + my($enc, $enclength, $encinput) = split(/:/, $input); + for(my $encidx = 0; $encidx < length($encinput); $encidx += 16) { + $output .= + $cipher->decrypt(pack("H16", substr($encinput, $encidx, 16))); + } + return substr($output, 0, $enclength); + } else { + return undef; + } } # @@ -234,32 +233,32 @@ sub Decipher { # register a duplicate command handler. # sub RegisterHandler { - my $RequestName = shift; - my $Procedure = shift; - my $MustEncode = shift; - my $ClientOk = shift; - my $ManagerOk = shift; - - # Don't allow duplication# - - if (defined $Dispatcher{$RequestName}) { - die "Attempting to define a duplicate request handler for $RequestName\n"; - } - # Build the client type mask: - - my $ClientTypeMask = 0; - if($ClientOk) { - $ClientTypeMask |= $CLIENT_OK; - } - if($ManagerOk) { - $ClientTypeMask |= $MANAGER_OK; - } + my $RequestName = shift; + my $Procedure = shift; + my $MustEncode = shift; + my $ClientOk = shift; + my $ManagerOk = shift; + + # Don't allow duplication# - # Enter the hash: + if (defined $Dispatcher{$RequestName}) { + die "Attempting to define a duplicate request handler for $RequestName\n"; + } + # Build the client type mask: + + my $ClientTypeMask = 0; + if($ClientOk) { + $ClientTypeMask |= $CLIENT_OK; + } + if($ManagerOk) { + $ClientTypeMask |= $MANAGER_OK; + } + + # Enter the hash: - my @entry = ($Procedure, $MustEncode, $ClientTypeMask); + my @entry = ($Procedure, $MustEncode, $ClientTypeMask); - $Dispatcher{$RequestName} = \@entry; + $Dispatcher{$RequestName} = \@entry; } @@ -284,13 +283,13 @@ sub RegisterHandler { # Reply information is sent to the client. sub PingHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; + my $cmd = shift; + my $tail = shift; + my $client = shift; - Reply( $client,"$currenthostid\n","$cmd:$tail"); + Reply( $client,"$currenthostid\n","$cmd:$tail"); - return 1; + return 1; } RegisterHandler("ping", \&PingHandler, 0, 1, 1); # Ping unencoded, client or manager. # @@ -309,13 +308,13 @@ RegisterHandler("ping", \&PingHandler, 0 # Reply information is sent to the client. sub PongHandler { - my $cmd = shift; - my $tail = shift; - my $replyfd = shift; - - my $reply=&reply("ping",$clientname); - Reply( $replyfd, "$currenthostid:$reply\n", "$cmd:$tail"); - return 1; + my $cmd = shift; + my $tail = shift; + my $replyfd = shift; + + my $reply=&reply("ping",$clientname); + Reply( $replyfd, "$currenthostid:$reply\n", "$cmd:$tail"); + return 1; } RegisterHandler("pong", \&PongHandler, 0, 1, 1); # Pong unencoded, client or manager @@ -339,24 +338,24 @@ RegisterHandler("pong", \&PongHandler, 0 # $cipher is set with a reference to a new IDEA encryption object. # sub EstablishKeyHandler { - my $cmd = shift; - my $tail = shift; - my $replyfd = shift; - - my $buildkey=time.$$.int(rand 100000); - $buildkey=~tr/1-6/A-F/; - $buildkey=int(rand 100000).$buildkey.int(rand 100000); - my $key=$currenthostid.$clientname; - $key=~tr/a-z/A-Z/; - $key=~tr/G-P/0-9/; - $key=~tr/Q-Z/0-9/; - $key=$key.$buildkey.$key.$buildkey.$key.$buildkey; - $key=substr($key,0,32); - my $cipherkey=pack("H32",$key); - $cipher=new IDEA $cipherkey; - Reply($replyfd, "$buildkey\n", "$cmd:$tail"); + my $cmd = shift; + my $tail = shift; + my $replyfd = shift; + + my $buildkey=time.$$.int(rand 100000); + $buildkey=~tr/1-6/A-F/; + $buildkey=int(rand 100000).$buildkey.int(rand 100000); + my $key=$currenthostid.$clientname; + $key=~tr/a-z/A-Z/; + $key=~tr/G-P/0-9/; + $key=~tr/Q-Z/0-9/; + $key=$key.$buildkey.$key.$buildkey.$key.$buildkey; + $key=substr($key,0,32); + my $cipherkey=pack("H32",$key); + $cipher=new IDEA $cipherkey; + Reply($replyfd, "$buildkey\n", "$cmd:$tail"); - return 1; + return 1; } RegisterHandler("ekey", \&EstablishKeyHandler, 0, 1,1); @@ -379,24 +378,24 @@ RegisterHandler("ekey", \&EstablishKeyHa # Side effects: # Reply information is sent to the client. sub LoadHandler { - my $cmd = shift; - my $tail = shift; - my $replyfd = shift; + my $cmd = shift; + my $tail = shift; + my $replyfd = shift; # Get the load average from /proc/loadavg and calculate it as a percentage of # the allowed load limit as set by the perl global variable lonLoadLim - my $loadavg; - my $loadfile=IO::File->new('/proc/loadavg'); + my $loadavg; + my $loadfile=IO::File->new('/proc/loadavg'); - $loadavg=<$loadfile>; - $loadavg =~ s/\s.*//g; # Extract the first field only. + $loadavg=<$loadfile>; + $loadavg =~ s/\s.*//g; # Extract the first field only. - my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'}; + my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'}; - Reply( $replyfd, "$loadpercent\n", "$cmd:$tail"); + Reply( $replyfd, "$loadpercent\n", "$cmd:$tail"); - return 1; + return 1; } RegisterHandler("load", \&LoadHandler, 0, 1, 0); @@ -422,14 +421,14 @@ RegisterHandler("load", \&LoadHandler, 0 # the reply is written to the client. # sub UserLoadHandler { - my $cmd = shift; - my $tail = shift; - my $replyfd = shift; - - my $userloadpercent=&userload(); - Reply($replyfd, "$userloadpercent\n", "$cmd:$tail"); + my $cmd = shift; + my $tail = shift; + my $replyfd = shift; - return 1; + my $userloadpercent=&userload(); + Reply($replyfd, "$userloadpercent\n", "$cmd:$tail"); + + return 1; } RegisterHandler("userload", \&UserLoadHandler, 0, 1, 0); @@ -447,24 +446,24 @@ RegisterHandler("userload", \&UserLoadHa # The user authorization type is written to the client. # sub UserAuthorizationType { - my $cmd = shift; - my $tail = shift; - my $replyfd = shift; - - my $userinput = "$cmd:$tail"; - - # Pull the domain and username out of the command tail. - # and call GetAuthType to determine the authentication type. - - my ($udom,$uname)=split(/:/,$tail); - my $result = GetAuthType($udom, $uname); - if($result eq "nouser") { - Failure( $replyfd, "unknown_user\n", $userinput); - } else { - Reply( $replyfd, "$result\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $replyfd = shift; + + my $userinput = "$cmd:$tail"; + + # Pull the domain and username out of the command tail. + # and call GetAuthType to determine the authentication type. + + my ($udom,$uname)=split(/:/,$tail); + my $result = GetAuthType($udom, $uname); + if($result eq "nouser") { + Failure( $replyfd, "unknown_user\n", $userinput); + } else { + Reply( $replyfd, "$result\n", $userinput); + } - return 1; + return 1; } RegisterHandler("currentauth", \&UserAuthorizationType, 1, 1, 0); # @@ -483,28 +482,28 @@ RegisterHandler("currentauth", \&UserAut # a reply is written to the client. sub PushFileHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; + my $cmd = shift; + my $tail = shift; + my $client = shift; - my $userinput = "$cmd:$tail"; + my $userinput = "$cmd:$tail"; - # At this time we only know that the IP of our partner is a valid manager - # the code below is a hook to do further authentication (e.g. to resolve - # spoofing). + # At this time we only know that the IP of our partner is a valid manager + # the code below is a hook to do further authentication (e.g. to resolve + # spoofing). - my $cert = GetCertificate($userinput); - if(ValidManager($cert)) { + my $cert = GetCertificate($userinput); + if(ValidManager($cert)) { - # Now presumably we have the bona fides of both the peer host and the - # process making the request. + # Now presumably we have the bona fides of both the peer host and the + # process making the request. - my $reply = PushFile($userinput); - Reply($client, "$reply\n", $userinput); + my $reply = PushFile($userinput); + Reply($client, "$reply\n", $userinput); - } else { - Failure( $client, "refused\n", $userinput); - } + } else { + Failure( $client, "refused\n", $userinput); + } } RegisterHandler("pushfile", \&PushFileHandler, 1, 0, 1); @@ -525,21 +524,21 @@ RegisterHandler("pushfile", \&PushFileHa # a reply is sent to the client. # sub ReinitProcessHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my $cert = GetCertificate($userinput); - if(ValidManager($cert)) { - chomp($userinput); - my $reply = ReinitProcess($userinput); - Reply( $client, "$reply\n", $userinput); - } else { - Failure( $client, "refused\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my $cert = GetCertificate($userinput); + if(ValidManager($cert)) { + chomp($userinput); + my $reply = ReinitProcess($userinput); + Reply( $client, "$reply\n", $userinput); + } else { + Failure( $client, "refused\n", $userinput); + } + return 1; } RegisterHandler("reinit", \&ReinitProcessHandler, 1, 0, 1); @@ -559,31 +558,31 @@ RegisterHandler("reinit", \&ReinitProces # a reply is sent to the client. # sub EditTableHandler { - my $command = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$command:$tail"; - - my $cert = GetCertificate($userinput); - if(ValidManager($cert)) { - my($filetype, $script) = split(/:/, $tail); - if (($filetype eq "hosts") || - ($filetype eq "domain")) { - if($script ne "") { - Reply($client, # BUGBUG - EditFile - EditFile($userinput), # could fail. - $userinput); - } else { - Failure($client,"refused\n",$userinput); - } - } else { - Failure($client,"refused\n",$userinput); - } - } else { - Failure($client,"refused\n",$userinput); - } - return 1; + my $command = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$command:$tail"; + + my $cert = GetCertificate($userinput); + if(ValidManager($cert)) { + my($filetype, $script) = split(/:/, $tail); + if (($filetype eq "hosts") || + ($filetype eq "domain")) { + if($script ne "") { + Reply($client, # BUGBUG - EditFile + EditFile($userinput), # could fail. + $userinput); + } else { + Failure($client,"refused\n",$userinput); + } + } else { + Failure($client,"refused\n",$userinput); + } + } else { + Failure($client,"refused\n",$userinput); + } + return 1; } RegisterHandler("edit", \&EditTableHandler, 1, 0, 1); @@ -598,8 +597,8 @@ RegisterHandler("edit", \&EditTableHandl # internal per user password file. # - kerberos - The user can be authenticated against either a kerb4 or kerb5 # ticket granting authority. -# - user - The person tailoring LonCAPA can supply a user authentication mechanism -# that is per system. +# - user - The person tailoring LonCAPA can supply a user authentication +# mechanism that is per system. # # Parameters: # $cmd - The command that got us here. @@ -613,133 +612,133 @@ RegisterHandler("edit", \&EditTableHandl # input into the authentication process that are described above. # sub AuthenticateHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - # Regenerate the full input line - - my $userinput = $cmd.":".$tail; - - # udom - User's domain. - # uname - Username. - # upass - User's password. - - my ($udom,$uname,$upass)=split(/:/,$tail); - Debug(" Authenticate domain = $udom, user = $uname, password = $upass"); - chomp($upass); - $upass=unescape($upass); - my $proname=propath($udom,$uname); - my $passfilename="$proname/passwd"; - - # The user's 'personal' loncapa passworrd file describes how to authenticate: - - if (-e $passfilename) { - Debug("Located password file: $passfilename"); - - my $pf = IO::File->new($passfilename); - my $realpasswd=<$pf>; - chomp($realpasswd); - my ($howpwd,$contentpwd)=split(/:/,$realpasswd); - my $pwdcorrect=0; - # - # Authenticate against password stored in the internal file. - # - Debug("Authenticating via $howpwd"); - if ($howpwd eq 'internal') { - &Debug("Internal auth"); - $pwdcorrect= (crypt($upass,$contentpwd) eq $contentpwd); - # - # Authenticate against the unix password file. - # - } elsif ($howpwd eq 'unix') { - &Debug("Unix auth"); - if((getpwnam($uname))[1] eq "") { #no such user! - $pwdcorrect = 0; - } else { - $contentpwd=(getpwnam($uname))[1]; - my $pwauth_path="/usr/local/sbin/pwauth"; - unless ($contentpwd eq 'x') { - $pwdcorrect= (crypt($upass,$contentpwd) eq $contentpwd); - } elsif (-e $pwauth_path) { - open PWAUTH, "|$pwauth_path" or - die "Cannot invoke authentication"; - print PWAUTH "$uname\n$upass\n"; - close PWAUTH; - $pwdcorrect=!$?; - } - } - # - # Authenticate against a Kerberos 4 server: - # - } elsif ($howpwd eq 'krb4') { - my $null=pack("C",0); - unless ($upass=~/$null/) { - my $krb4_error = &Authen::Krb4::get_pw_in_tkt($uname, - "", - $contentpwd, - 'krbtgt', - $contentpwd, - 1, - $upass); - if (!$krb4_error) { - $pwdcorrect = 1; - } else { - $pwdcorrect=0; - # log error if it is not a bad password - if ($krb4_error != 62) { - &logthis('krb4:'.$uname.','.$contentpwd.','. - &Authen::Krb4::get_err_txt($Authen::Krb4::error)); - } - } - } - # - # Authenticate against a Kerberos 5 server: - # - } elsif ($howpwd eq 'krb5') { - my $null=pack("C",0); - unless ($upass=~/$null/) { - my $krbclient=&Authen::Krb5::parse_name($uname.'@'.$contentpwd); - my $krbservice="krbtgt/".$contentpwd."\@".$contentpwd; - 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, - $krbserver, - $upass, - $credentials); - $pwdcorrect = ($krbreturn == 1); - } else { - $pwdcorrect=0; - } - # - # Finally, the user may have written in an authentication module. - # in that case, if requested, authenticate against it. - # - } elsif ($howpwd eq 'localauth') { - $pwdcorrect=&localauth::localauth($uname,$upass,$contentpwd); - } - # - # Successfully authorized. - # - if ($pwdcorrect) { - Reply( $client, "authorized\n", $userinput); - # - # Bad credentials: Failed to authorize - # - } else { - Failure( $client, "non_authorized\n", $userinput); - } - # - # User bad... note it may be bad security practice to differntiate to the - # caller a bad user from a bad passwd... since that supplies covert channel - # information (you have a good user but bad password e.g.) to guessers. - # - } else { - Failure( $client, "unknown_user\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + # Regenerate the full input line + + my $userinput = $cmd.":".$tail; + + # udom - User's domain. + # uname - Username. + # upass - User's password. + + my ($udom,$uname,$upass)=split(/:/,$tail); + Debug(" Authenticate domain = $udom, user = $uname, password = $upass"); + chomp($upass); + $upass=unescape($upass); + my $proname=propath($udom,$uname); + my $passfilename="$proname/passwd"; + + # The user's 'personal' loncapa passworrd file describes how to authenticate: + + if (-e $passfilename) { + Debug("Located password file: $passfilename"); + + my $pf = IO::File->new($passfilename); + my $realpasswd=<$pf>; + chomp($realpasswd); + my ($howpwd,$contentpwd)=split(/:/,$realpasswd); + my $pwdcorrect=0; + # + # Authenticate against password stored in the internal file. + # + Debug("Authenticating via $howpwd"); + if ($howpwd eq 'internal') { + &Debug("Internal auth"); + $pwdcorrect= (crypt($upass,$contentpwd) eq $contentpwd); + # + # Authenticate against the unix password file. + # + } elsif ($howpwd eq 'unix') { + &Debug("Unix auth"); + if((getpwnam($uname))[1] eq "") { #no such user! + $pwdcorrect = 0; + } else { + $contentpwd=(getpwnam($uname))[1]; + my $pwauth_path="/usr/local/sbin/pwauth"; + unless ($contentpwd eq 'x') { + $pwdcorrect= (crypt($upass,$contentpwd) eq $contentpwd); + } elsif (-e $pwauth_path) { + open PWAUTH, "|$pwauth_path" or + die "Cannot invoke authentication"; + print PWAUTH "$uname\n$upass\n"; + close PWAUTH; + $pwdcorrect=!$?; + } + } + # + # Authenticate against a Kerberos 4 server: + # + } elsif ($howpwd eq 'krb4') { + my $null=pack("C",0); + unless ($upass=~/$null/) { + my $krb4_error = &Authen::Krb4::get_pw_in_tkt($uname, + "", + $contentpwd, + 'krbtgt', + $contentpwd, + 1, + $upass); + if (!$krb4_error) { + $pwdcorrect = 1; + } else { + $pwdcorrect=0; + # log error if it is not a bad password + if ($krb4_error != 62) { + &logthis('krb4:'.$uname.','.$contentpwd.','. + &Authen::Krb4::get_err_txt($Authen::Krb4::error)); + } + } + } + # + # Authenticate against a Kerberos 5 server: + # + } elsif ($howpwd eq 'krb5') { + my $null=pack("C",0); + unless ($upass=~/$null/) { + my $krbclient=&Authen::Krb5::parse_name($uname.'@'.$contentpwd); + my $krbservice="krbtgt/".$contentpwd."\@".$contentpwd; + 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, + $krbserver, + $upass, + $credentials); + $pwdcorrect = ($krbreturn == 1); + } else { + $pwdcorrect=0; + } + # + # Finally, the user may have written in an authentication module. + # in that case, if requested, authenticate against it. + # + } elsif ($howpwd eq 'localauth') { + $pwdcorrect=&localauth::localauth($uname,$upass,$contentpwd); + } + # + # Successfully authorized. + # + if ($pwdcorrect) { + Reply( $client, "authorized\n", $userinput); + # + # Bad credentials: Failed to authorize + # + } else { + Failure( $client, "non_authorized\n", $userinput); + } + # + # User bad... note it may be bad security practice to + # differntiate to the caller a bad user from a bad + # passwd... since that supplies covert channel information + # (you have a good user but bad password e.g.) to guessers. + # + } else { + Failure( $client, "unknown_user\n", $userinput); + } + return 1; } RegisterHandler("auth", \&AuthenticateHandler, 1, 1, 0); @@ -765,97 +764,97 @@ RegisterHandler("auth", \&AuthenticateHa # The authentication systems describe above have their own forms of implicit # input into the authentication process that are described above. sub ChangePasswordHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = $cmd.":".$tail; # Reconstruct client's string. - - # - # udom - user's domain. - # uname - Username. - # upass - Current password. - # npass - New password. - - my ($udom,$uname,$upass,$npass)=split(/:/,$tail); - chomp($npass); - $upass=&unescape($upass); - $npass=&unescape($npass); - &Debug("Trying to change password for $uname"); - my $proname=propath($udom,$uname); - my $passfilename="$proname/passwd"; - if (-e $passfilename) { - my $realpasswd; - { - my $pf = IO::File->new($passfilename); - $realpasswd=<$pf>; - } - chomp($realpasswd); - my ($howpwd,$contentpwd)=split(/:/,$realpasswd); - if ($howpwd eq 'internal') { - &Debug("internal auth"); - if (crypt($upass,$contentpwd) eq $contentpwd) { - my $salt=time; - $salt=substr($salt,6,2); - my $ncpass=crypt($npass,$salt); - { - my $pf = IO::File->new(">$passfilename"); - if ($pf) { - print $pf "internal:$ncpass\n"; - &logthis("Result of password change for " - ."$uname: pwchange_success"); - Reply($client, "ok\n", $userinput); - } else { - &logthis("Unable to open $uname passwd " - ."to change password"); - Failure( $client, "non_authorized\n",$userinput); - } - } - } else { - Failure($client, "non_authorized\n", $userinput); - } - } elsif ($howpwd eq 'unix') { - # Unix means we have to access /etc/password - # one way or another. - # First: Make sure the current password is - # correct - &Debug("auth is unix"); - $contentpwd=(getpwnam($uname))[1]; - my $pwdcorrect = "0"; - my $pwauth_path="/usr/local/sbin/pwauth"; - unless ($contentpwd eq 'x') { - $pwdcorrect= (crypt($upass,$contentpwd) eq $contentpwd); - } elsif (-e $pwauth_path) { - open PWAUTH, "|$pwauth_path" or - die "Cannot invoke authentication"; - print PWAUTH "$uname\n$upass\n"; - close PWAUTH; - &Debug("exited pwauth with $? ($uname,$upass) "); - $pwdcorrect=($? == 0); - } - if ($pwdcorrect) { - my $execdir=$perlvar{'lonDaemons'}; - &Debug("Opening lcpasswd pipeline"); - my $pf = IO::File->new("|$execdir/lcpasswd > " - ."$perlvar{'lonDaemons'}" - ."/logs/lcpasswd.log"); - print $pf "$uname\n$npass\n$npass\n"; - close $pf; - my $err = $?; - my $result = ($err>0 ? 'pwchange_failure' : 'ok'); - &logthis("Result of password change for $uname: ". - &lcpasswdstrerror($?)); - Reply($client, "$result\n", $userinput); - } else { - Reply($client, "non_authorized\n", $userinput); - } - } else { - Reply( $client, "auth_mode_error\n", $userinput); - } - } else { - Reply( $client, "unknown_user\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = $cmd.":".$tail; # Reconstruct client's string. + + # + # udom - user's domain. + # uname - Username. + # upass - Current password. + # npass - New password. + + my ($udom,$uname,$upass,$npass)=split(/:/,$tail); + chomp($npass); + $upass=&unescape($upass); + $npass=&unescape($npass); + &Debug("Trying to change password for $uname"); + my $proname=propath($udom,$uname); + my $passfilename="$proname/passwd"; + if (-e $passfilename) { + my $realpasswd; + { + my $pf = IO::File->new($passfilename); + $realpasswd=<$pf>; + } + chomp($realpasswd); + my ($howpwd,$contentpwd)=split(/:/,$realpasswd); + if ($howpwd eq 'internal') { + &Debug("internal auth"); + if (crypt($upass,$contentpwd) eq $contentpwd) { + my $salt=time; + $salt=substr($salt,6,2); + my $ncpass=crypt($npass,$salt); + { + my $pf = IO::File->new(">$passfilename"); + if ($pf) { + print $pf "internal:$ncpass\n"; + &logthis("Result of password change for " + ."$uname: pwchange_success"); + Reply($client, "ok\n", $userinput); + } else { + &logthis("Unable to open $uname passwd " + ."to change password"); + Failure( $client, "non_authorized\n",$userinput); + } + } + } else { + Failure($client, "non_authorized\n", $userinput); + } + } elsif ($howpwd eq 'unix') { + # Unix means we have to access /etc/password + # one way or another. + # First: Make sure the current password is + # correct + &Debug("auth is unix"); + $contentpwd=(getpwnam($uname))[1]; + my $pwdcorrect = "0"; + my $pwauth_path="/usr/local/sbin/pwauth"; + unless ($contentpwd eq 'x') { + $pwdcorrect= (crypt($upass,$contentpwd) eq $contentpwd); + } elsif (-e $pwauth_path) { + open PWAUTH, "|$pwauth_path" or + die "Cannot invoke authentication"; + print PWAUTH "$uname\n$upass\n"; + close PWAUTH; + &Debug("exited pwauth with $? ($uname,$upass) "); + $pwdcorrect=($? == 0); + } + if ($pwdcorrect) { + my $execdir=$perlvar{'lonDaemons'}; + &Debug("Opening lcpasswd pipeline"); + my $pf = IO::File->new("|$execdir/lcpasswd > " + ."$perlvar{'lonDaemons'}" + ."/logs/lcpasswd.log"); + print $pf "$uname\n$npass\n$npass\n"; + close $pf; + my $err = $?; + my $result = ($err>0 ? 'pwchange_failure' : 'ok'); + &logthis("Result of password change for $uname: ". + &lcpasswdstrerror($?)); + Reply($client, "$result\n", $userinput); + } else { + Reply($client, "non_authorized\n", $userinput); + } + } else { + Reply( $client, "auth_mode_error\n", $userinput); + } + } else { + Reply( $client, "unknown_user\n", $userinput); + } + return 1; } RegisterHandler("passwd", \&ChangePasswordHandler, 1, 1, 0); @@ -876,46 +875,46 @@ RegisterHandler("passwd", \&ChangePasswo # The authentication systems describe above have their own forms of implicit # input into the authentication process that are described above. sub AddUserHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = $cmd.":".$tail; - - my $oldumask=umask(0077); - my ($udom,$uname,$umode,$npass)=split(/:/,$tail); - &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) { - Failure( $client, "already_exists\n", $userinput); - } elsif ($udom ne $currentdomainid) { - Failure($client, "not_right_domain\n", $userinput); - } 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); - Reply($client, $result, $userinput); #BUGBUG - could be fail - } else { - Failure($client, "$fperror\n", $userinput); - } - } - umask($oldumask); - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = $cmd.":".$tail; + + my $oldumask=umask(0077); + my ($udom,$uname,$umode,$npass)=split(/:/,$tail); + &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) { + Failure( $client, "already_exists\n", $userinput); + } elsif ($udom ne $currentdomainid) { + Failure($client, "not_right_domain\n", $userinput); + } 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); + Reply($client, $result, $userinput); #BUGBUG - could be fail + } else { + Failure($client, "$fperror\n", $userinput); + } + } + umask($oldumask); + return 1; } RegisterHandler("makeuser", \&AddUserHandler, 1, 1, 0); @@ -943,25 +942,25 @@ RegisterHandler("makeuser", \&AddUserHan # input into the authentication process that are described above. # sub ChangeAuthenticationHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; # Reconstruct user input. - - my ($udom,$uname,$umode,$npass)=split(/:/,$tail); - 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) { - Failure( $client, "not_right_domain\n", $client); - } else { - my $result=&make_passwd_file($uname, $umode,$npass,$passfilename); - Reply($client, $result, $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; # Reconstruct user input. + + my ($udom,$uname,$umode,$npass)=split(/:/,$tail); + 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) { + Failure( $client, "not_right_domain\n", $client); + } else { + my $result=&make_passwd_file($uname, $umode,$npass,$passfilename); + Reply($client, $result, $userinput); + } + return 1; } RegisterHandler("changeuserauth", \&ChangeAuthenticationHandler, 1,1, 0); @@ -982,21 +981,21 @@ RegisterHandler("changeuserauth", \&Chan # input into the authentication process that are described above. # sub IsHomeHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($udom,$uname)=split(/:/,$tail); - chomp($uname); - my $proname=propath($udom,$uname); - if (-e $proname) { - Reply( $client, "found\n", $userinput); - } else { - Failure($client, "not_found\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($udom,$uname)=split(/:/,$tail); + chomp($uname); + my $proname=propath($udom,$uname); + if (-e $proname) { + Reply( $client, "found\n", $userinput); + } else { + Failure($client, "not_found\n", $userinput); + } + return 1; } RegisterHandler("home", \&IsHomeHandler, 0,1,0); # @@ -1022,62 +1021,62 @@ RegisterHandler("home", \&IsHomeHandler, # input into the authentication process that are described above. # sub UpdateResourceHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my $fname=$tail; - 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; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my $fname=$tail; + 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; } RegisterHandler("update", \&UpdateResourceHandler, 0 ,1, 0); @@ -1092,49 +1091,49 @@ RegisterHandler("update", \&UpdateResour # 1 - Continue processing. # sub FetchUserFileHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - 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; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + 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; } RegisterHandler("fetchuserfile", \&FetchUserFileHandler, 0, 1, 0); # @@ -1150,26 +1149,26 @@ RegisterHandler("fetchuserfile", \&Fetch # 0 - Requested to exit, caller should shut down. # 1 - Continue processing. sub AuthenticateUserFileAccess { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($fname,$session)=split(/:/,$tail); - chomp($session); - my $reply='non_auth'; - if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'.$session.'.id')) { - while (my $line=) { - if ($line=~/userfile\.$fname\=/) { - $reply='ok'; - } - } - close(ENVIN); - Reply($client, $reply."\n", $userinput); - } else { - Failure($client, "invalid_token\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($fname,$session)=split(/:/,$tail); + chomp($session); + my $reply='non_auth'; + if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'.$session.'.id')) { + while (my $line=) { + if ($line=~/userfile\.$fname\=/) { + $reply='ok'; + } + } + close(ENVIN); + Reply($client, $reply."\n", $userinput); + } else { + Failure($client, "invalid_token\n", $userinput); + } + return 1; } RegisterHandler("tokenauthuserfile", \&AuthenticateUserFileAccess, 0, 1, 0); @@ -1185,18 +1184,18 @@ RegisterHandler("tokenauthuserfile", \&A # 1 - Continue processing. # sub UnsubscribeHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput= "$cmd:$tail"; - - my $fname = $tail; - if (-e $fname) { - Reply($client, &unsub($client,$fname,$clientip), $userinput); - } else { - Failure($client, "not_found\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput= "$cmd:$tail"; + + my $fname = $tail; + if (-e $fname) { + Reply($client, &unsub($client,$fname,$clientip), $userinput); + } else { + Failure($client, "not_found\n", $userinput); + } + return 1; } RegisterHandler("unusb", \&UnsubscribeHandler, 0, 1, 0); @@ -1211,14 +1210,14 @@ RegisterHandler("unusb", \&UnsubscribeHa # 1 - Continue processing. # sub SubscribeHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; - Reply( $client, &subscribe($userinput,$clientip), $userinput); - - return 1; + Reply( $client, &subscribe($userinput,$clientip), $userinput); + + return 1; } RegisterHandler("sub", \&SubscribeHandler, 0, 1, 0); @@ -1236,14 +1235,14 @@ RegisterHandler("sub", \&SubscribeHandle # 1 - Continue processing. # sub CurrentVersionHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput= "$cmd:$tail"; - - my $fname = $tail; - Reply( $client, ¤tversion($fname)."\n", $userinput); - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput= "$cmd:$tail"; + + my $fname = $tail; + Reply( $client, ¤tversion($fname)."\n", $userinput); + return 1; } RegisterHandler("currentversion", \&CurrentVersionHandler, 0, 1, 0); @@ -1260,26 +1259,26 @@ RegisterHandler("currentversion", \&Curr # 1 - Continue processing. # sub ActivityLogEntryHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - 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 { - Reply($client, "error: ".($!+0)." IO::File->new Failed " - ."while attempting log\n", - $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + 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 { + Reply($client, "error: ".($!+0)." IO::File->new Failed " + ."while attempting log\n", + $userinput); + } - return 1; + return 1; } RegisterHandler("log", \&ActivityLogEntryHandler, 0, 1, 0); # @@ -1297,48 +1296,48 @@ RegisterHandler("log", \&ActivityLogEntr # 1 - Continue processing. # sub PutUserProfileEntry { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($udom,$uname,$namespace,$what) =split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - if ($namespace ne 'roles') { - chomp($what); - my $proname=propath($udom,$uname); - my $now=time; - unless ($namespace=~/^nohist\_/) { - my $hfh; - if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { - print $hfh "P:$now:$what\n"; - } - } - my @pairs=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", - &GDBM_WRCREAT(),0640)) { - foreach my $pair (@pairs) { - my ($key,$value)=split(/=/,$pair); - $hash{$key}=$value; - } - if (untie(%hash)) { - 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); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($udom,$uname,$namespace,$what) =split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + if ($namespace ne 'roles') { + chomp($what); + my $proname=propath($udom,$uname); + my $now=time; + unless ($namespace=~/^nohist\_/) { + my $hfh; + if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { + print $hfh "P:$now:$what\n"; + } + } + my @pairs=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", + &GDBM_WRCREAT(),0640)) { + foreach my $pair (@pairs) { + my ($key,$value)=split(/=/,$pair); + $hash{$key}=$value; + } + if (untie(%hash)) { + 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; + return 1; } RegisterHandler("put", \&PutUserProfileEntry, 0, 1, 0); @@ -1358,51 +1357,51 @@ RegisterHandler("put", \&PutUserProfileE # 1 - Continue processing. # sub IncrementUserValueHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = shift; - - my ($udom,$uname,$namespace,$what) =split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - if ($namespace ne 'roles') { - chomp($what); - my $proname=propath($udom,$uname); - my $now=time; - unless ($namespace=~/^nohist\_/) { - my $hfh; - if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { - print $hfh "P:$now:$what\n"; - } - } - my @pairs=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(), - 0640)) { - 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)) { - Reply( $client, "ok\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) failed ". - "while attempting put\n", $userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting put\n", $userinput); - } - } else { - Failure($client, "refused\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = shift; + + my ($udom,$uname,$namespace,$what) =split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + if ($namespace ne 'roles') { + chomp($what); + my $proname=propath($udom,$uname); + my $now=time; + unless ($namespace=~/^nohist\_/) { + my $hfh; + if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { + print $hfh "P:$now:$what\n"; + } + } + my @pairs=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(), + 0640)) { + 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)) { + Reply( $client, "ok\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) failed ". + "while attempting put\n", $userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting put\n", $userinput); + } + } else { + Failure($client, "refused\n", $userinput); + } - return 1; + return 1; } RegisterHandler("inc", \&IncrementUserValueHandler, 0, 1, 0); # @@ -1426,49 +1425,49 @@ RegisterHandler("inc", \&IncrementUserVa # # sub RolesPutHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($exedom,$exeuser,$udom,$uname,$what) =split(/:/,$tail); - &Debug("cmd = ".$cmd." exedom= ".$exedom."user = ".$exeuser." udom=".$udom. - "what = ".$what); - my $namespace='roles'; - chomp($what); - my $proname=propath($udom,$uname); - my $now=time; - # - # 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. - { - my $hfh; - if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { - print $hfh "P:$now:$exedom:$exeuser:$what\n"; - } - } - my @pairs=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_WRCREAT(),0640)) { - foreach my $pair (@pairs) { - my ($key,$value)=split(/=/,$pair); + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($exedom,$exeuser,$udom,$uname,$what) =split(/:/,$tail); + &Debug("cmd = ".$cmd." exedom= ".$exedom."user = ".$exeuser." udom=".$udom. + "what = ".$what); + my $namespace='roles'; + chomp($what); + my $proname=propath($udom,$uname); + my $now=time; + # + # 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. + { + my $hfh; + if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { + print $hfh "P:$now:$exedom:$exeuser:$what\n"; + } + } + my @pairs=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_WRCREAT(),0640)) { + foreach my $pair (@pairs) { + my ($key,$value)=split(/=/,$pair); &ManagePermissions($key, $udom, $uname, &GetAuthType( $udom, $uname)); $hash{$key}=$value; - } - if (untie(%hash)) { - 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; + } + if (untie(%hash)) { + 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; } RegisterHandler("rolesput", \&RolesPutHandler, 1,1,0); # Encoded client only. # @@ -1489,48 +1488,48 @@ RegisterHandler("rolesput", \&RolesPutHa # 0 - Exit. # sub RolesDeleteHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($exedom,$exeuser,$udom,$uname,$what)=split(/:/,$tail); - &Debug("cmd = ".$cmd." exedom= ".$exedom."user = ".$exeuser." udom=".$udom. - "what = ".$what); - my $namespace='roles'; - chomp($what); - my $proname=propath($udom,$uname); - my $now=time; - # - # Log the attempt. This {}'ing is done to ensure that the - # logfile is flushed and closed as quickly as possible. Hopefully - # this preserves both time ordering and reduces the probability that - # messages will be interleaved. - # - { - my $hfh; - if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { - print $hfh "D:$now:$exedom:$exeuser:$what\n"; - } - } - my @rolekeys=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_WRCREAT(),0640)) { - foreach my $key (@rolekeys) { - delete $hash{$key}; - } - if (untie(%hash)) { - Reply($client, "ok\n", $userinput); - } else { - Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting rolesdel\n", $userinput); - } - } else { - Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting rolesdel\n", $userinput); - } - - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($exedom,$exeuser,$udom,$uname,$what)=split(/:/,$tail); + &Debug("cmd = ".$cmd." exedom= ".$exedom."user = ".$exeuser." udom=".$udom. + "what = ".$what); + my $namespace='roles'; + chomp($what); + my $proname=propath($udom,$uname); + my $now=time; + # + # Log the attempt. This {}'ing is done to ensure that the + # logfile is flushed and closed as quickly as possible. Hopefully + # this preserves both time ordering and reduces the probability that + # messages will be interleaved. + # + { + my $hfh; + if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { + print $hfh "D:$now:$exedom:$exeuser:$what\n"; + } + } + my @rolekeys=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_WRCREAT(),0640)) { + foreach my $key (@rolekeys) { + delete $hash{$key}; + } + if (untie(%hash)) { + Reply($client, "ok\n", $userinput); + } else { + Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting rolesdel\n", $userinput); + } + } else { + Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting rolesdel\n", $userinput); + } + + return 1; } RegisterHandler("rolesdel", \&RolesDeleteHandler, 1,1, 0); # Encoded client only @@ -1554,40 +1553,40 @@ RegisterHandler("rolesdel", \&RolesDelet # 0 - Exit. # sub GetProfileEntry { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput= "$cmd:$tail"; - - my ($udom,$uname,$namespace,$what) = split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - chomp($what); - my @queries=split(/\&/,$what); - my $proname=propath($udom,$uname); - my $qresult=''; - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_READER(),0640)) { - for (my $i=0;$i<=$#queries;$i++) { - $qresult.="$hash{$queries[$i]}&"; # Presumably failure gives empty string. - } - if (untie(%hash)) { - $qresult=~s/\&$//; # Remove trailing & from last lookup. - Reply($client, "$qresult\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting get\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); - } - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput= "$cmd:$tail"; + + my ($udom,$uname,$namespace,$what) = split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + chomp($what); + my @queries=split(/\&/,$what); + my $proname=propath($udom,$uname); + my $qresult=''; + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_READER(),0640)) { + for (my $i=0;$i<=$#queries;$i++) { + $qresult.="$hash{$queries[$i]}&"; # Presumably failure gives empty string. + } + if (untie(%hash)) { + $qresult=~s/\&$//; # Remove trailing & from last lookup. + Reply($client, "$qresult\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting get\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); + } + } + return 1; } RegisterHandler("get", \&GetProfileEntry, 0,1,0); # @@ -1610,48 +1609,48 @@ RegisterHandler("get", \&GetProfileEntry # 1 - Continue processing # 0 - server should exit. sub GetProfileEntryEncrypted { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($cmd,$udom,$uname,$namespace,$what) = split(/:/,$userinput); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - chomp($what); - my @queries=split(/\&/,$what); - my $proname=propath($udom,$uname); - my $qresult=''; - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) { - for (my $i=0;$i<=$#queries;$i++) { - $qresult.="$hash{$queries[$i]}&"; - } - if (untie(%hash)) { - $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); - } - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting eget\n", $userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting eget\n", $userinput); - } - - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($cmd,$udom,$uname,$namespace,$what) = split(/:/,$userinput); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + chomp($what); + my @queries=split(/\&/,$what); + my $proname=propath($udom,$uname); + my $qresult=''; + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) { + for (my $i=0;$i<=$#queries;$i++) { + $qresult.="$hash{$queries[$i]}&"; + } + if (untie(%hash)) { + $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); + } + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting eget\n", $userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting eget\n", $userinput); + } + + return 1; } RegisterHandler("eget", \&GetProfileEncrypted, 0, 1, 0); @@ -1674,40 +1673,40 @@ RegisterHandler("eget", \&GetProfileEncr # # sub DeletProfileEntry { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "cmd:$tail"; - - my ($udom,$uname,$namespace,$what) = split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - chomp($what); - my $proname=propath($udom,$uname); - my $now=time; - unless ($namespace=~/^nohist\_/) { - my $hfh; - if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { - print $hfh "D:$now:$what\n"; - } - } - my @keys=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) { - foreach my $key (@keys) { - delete($hash{$key}); - } - if (untie(%hash)) { - Reply($client, "ok\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting del\n", $userinput); - } - } else { - Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting del\n", $userinput); - } - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "cmd:$tail"; + + my ($udom,$uname,$namespace,$what) = split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + chomp($what); + my $proname=propath($udom,$uname); + my $now=time; + unless ($namespace=~/^nohist\_/) { + my $hfh; + if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { + print $hfh "D:$now:$what\n"; + } + } + my @keys=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) { + foreach my $key (@keys) { + delete($hash{$key}); + } + if (untie(%hash)) { + Reply($client, "ok\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting del\n", $userinput); + } + } else { + Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting del\n", $userinput); + } + return 1; } RegisterHandler("del", \&DeleteProfileEntry, 0, 1, 0); # @@ -1726,34 +1725,34 @@ RegisterHandler("del", \&DeleteProfileEn # 0 - Exit the server. # sub GetProfileKeys { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($udom,$uname,$namespace)=split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - my $proname=propath($udom,$uname); - my $qresult=''; - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) { - foreach my $key (keys %hash) { - $qresult.="$key&"; - } - if (untie(%hash)) { - $qresult=~s/\&$//; - Reply($client, "$qresult\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting keys\n", $userinput); - } - } else { - Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting keys\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($udom,$uname,$namespace)=split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + my $proname=propath($udom,$uname); + my $qresult=''; + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) { + foreach my $key (keys %hash) { + $qresult.="$key&"; + } + if (untie(%hash)) { + $qresult=~s/\&$//; + Reply($client, "$qresult\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting keys\n", $userinput); + } + } else { + Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting keys\n", $userinput); + } - return 1; + return 1; } RegisterHandler("keys", \&GetProfileKeys, 0, 1, 0); # @@ -1776,55 +1775,55 @@ RegisterHandler("keys", \&GetProfileKeys # 0 - Exit the server. # sub DumpProfileDatabase { - my $cmd = shift; - my $tail = shift; - my $client = shift; - my $userinput = "$cmd:$tail"; - - my ($udom,$uname,$namespace) = split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - my $qresult=''; - my $proname=propath($udom,$uname); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_READER(),0640)) { - # Structure of %data: - # $data{$symb}->{$parameter}=$value; - # $data{$symb}->{'v.'.$parameter}=$version; - # since $parameter will be unescaped, we do not - # have to worry about silly parameter names... - my %data = (); # A hash of anonymous hashes.. - while (my ($key,$value) = each(%hash)) { - my ($v,$symb,$param) = split(/:/,$key); - next if ($v eq 'version' || $symb eq 'keys'); - next if (exists($data{$symb}) && - exists($data{$symb}->{$param}) && - $data{$symb}->{'v.'.$param} > $v); - $data{$symb}->{$param}=$value; - $data{$symb}->{'v.'.$param}=$v; - } - if (untie(%hash)) { - while (my ($symb,$param_hash) = each(%data)) { - while(my ($param,$value) = each (%$param_hash)){ - next if ($param =~ /^v\./); # Ignore versions... - # - # Just dump the symb=value pairs separated by & - # - $qresult.=$symb.':'.$param.'='.$value.'&'; - } - } - chop($qresult); - Reply($client , "$qresult\n", $userinput); - } else { - Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting currentdump\n", $userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting currentdump\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + my $userinput = "$cmd:$tail"; + + my ($udom,$uname,$namespace) = split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + my $qresult=''; + my $proname=propath($udom,$uname); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", &GDBM_READER(),0640)) { + # Structure of %data: + # $data{$symb}->{$parameter}=$value; + # $data{$symb}->{'v.'.$parameter}=$version; + # since $parameter will be unescaped, we do not + # have to worry about silly parameter names... + my %data = (); # A hash of anonymous hashes.. + while (my ($key,$value) = each(%hash)) { + my ($v,$symb,$param) = split(/:/,$key); + next if ($v eq 'version' || $symb eq 'keys'); + next if (exists($data{$symb}) && + exists($data{$symb}->{$param}) && + $data{$symb}->{'v.'.$param} > $v); + $data{$symb}->{$param}=$value; + $data{$symb}->{'v.'.$param}=$v; + } + if (untie(%hash)) { + while (my ($symb,$param_hash) = each(%data)) { + while(my ($param,$value) = each (%$param_hash)){ + next if ($param =~ /^v\./); # Ignore versions... + # + # Just dump the symb=value pairs separated by & + # + $qresult.=$symb.':'.$param.'='.$value.'&'; + } + } + chop($qresult); + Reply($client , "$qresult\n", $userinput); + } else { + Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting currentdump\n", $userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting currentdump\n", $userinput); + } - return 1; + return 1; } RegisterHandler("currentdump", \&DumpProfileDatabase, 0, 1, 0); # @@ -1852,47 +1851,47 @@ RegisterHandler("currentdump", \&DumpPro # response is written to $client. # sub DumpWithRegexp { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($udom,$uname,$namespace,$regexp)=split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - if (defined($regexp)) { - $regexp=&unescape($regexp); - } else { - $regexp='.'; - } - my $qresult=''; - my $proname=propath($udom,$uname); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", - &GDBM_READER(),0640)) { - study($regexp); - while (my ($key,$value) = each(%hash)) { - if ($regexp eq '.') { - $qresult.=$key.'='.$value.'&'; - } else { - my $unescapeKey = &unescape($key); - if (eval('$unescapeKey=~/$regexp/')) { - $qresult.="$key=$value&"; - } - } - } - if (untie(%hash)) { - chop($qresult); - Reply($client, "$qresult\n", $userinput); - } else { - Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting dump\n", $userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting dump\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($udom,$uname,$namespace,$regexp)=split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + if (defined($regexp)) { + $regexp=&unescape($regexp); + } else { + $regexp='.'; + } + my $qresult=''; + my $proname=propath($udom,$uname); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", + &GDBM_READER(),0640)) { + study($regexp); + while (my ($key,$value) = each(%hash)) { + if ($regexp eq '.') { + $qresult.=$key.'='.$value.'&'; + } else { + my $unescapeKey = &unescape($key); + if (eval('$unescapeKey=~/$regexp/')) { + $qresult.="$key=$value&"; + } + } + } + if (untie(%hash)) { + chop($qresult); + Reply($client, "$qresult\n", $userinput); + } else { + Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting dump\n", $userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting dump\n", $userinput); + } return 1; } @@ -1917,57 +1916,57 @@ RegisterHandler("dump", \&DumpWithRegexp # Side-Effects: # Writes to the client sub StoreHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; + my $cmd = shift; + my $tail = shift; + my $client = shift; - my $userinput = "$cmd:$tail"; + my $userinput = "$cmd:$tail"; - my ($udom,$uname,$namespace,$rid,$what) =split(/:/,$tail); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - if ($namespace ne 'roles') { - chomp($what); - my $proname=propath($udom,$uname); - my $now=time; - unless ($namespace=~/^nohist\_/) { - my $hfh; - if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { - print $hfh "P:$now:$rid:$what\n"; - } + my ($udom,$uname,$namespace,$rid,$what) =split(/:/,$tail); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + if ($namespace ne 'roles') { + chomp($what); + my $proname=propath($udom,$uname); + my $now=time; + unless ($namespace=~/^nohist\_/) { + my $hfh; + if ($hfh=IO::File->new(">>$proname/$namespace.hist")) { + print $hfh "P:$now:$rid:$what\n"; + } + } + my @pairs=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", + &GDBM_WRCREAT(),0640)) { + my @previouskeys=split(/&/,$hash{"keys:$rid"}); + my $key; + $hash{"version:$rid"}++; + my $version=$hash{"version:$rid"}; + my $allkeys=''; + foreach my $pair (@pairs) { + my ($key,$value)=split(/=/,$pair); + $allkeys.=$key.':'; + $hash{"$version:$rid:$key"}=$value; + } + $hash{"$version:$rid:timestamp"}=$now; + $allkeys.='timestamp'; + $hash{"$version:keys:$rid"}=$allkeys; + if (untie(%hash)) { + Reply($client, "ok\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting store\n", $userinput); + } + } else { + Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting store\n", $userinput); + } + } else { + Failure($client, "refused\n", $userinput); } - my @pairs=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", - &GDBM_WRCREAT(),0640)) { - my @previouskeys=split(/&/,$hash{"keys:$rid"}); - my $key; - $hash{"version:$rid"}++; - my $version=$hash{"version:$rid"}; - my $allkeys=''; - foreach my $pair (@pairs) { - my ($key,$value)=split(/=/,$pair); - $allkeys.=$key.':'; - $hash{"$version:$rid:$key"}=$value; - } - $hash{"$version:$rid:timestamp"}=$now; - $allkeys.='timestamp'; - $hash{"$version:keys:$rid"}=$allkeys; - if (untie(%hash)) { - Reply($client, "ok\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting store\n", $userinput); - } - } else { - Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting store\n", $userinput); - } - } else { - Failure($client, "refused\n", $userinput); - } - return 1; + return 1; } RegisterHandler("store", \&StoreHandler, 0, 1, 0); # @@ -1987,46 +1986,46 @@ RegisterHandler("store", \&StoreHandler, # Writes a reply to the client. # sub RestoreHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; # Only used for logging purposes. - - my ($cmd,$udom,$uname,$namespace,$rid) = split(/:/,$userinput); - $namespace=~s/\//\_/g; - $namespace=~s/\W//g; - chomp($rid); - my $proname=propath($udom,$uname); - my $qresult=''; - my %hash; - if (tie(%hash,'GDBM_File',"$proname/$namespace.db", - &GDBM_READER(),0640)) { - my $version=$hash{"version:$rid"}; - $qresult.="version=$version&"; - my $scope; - for ($scope=1;$scope<=$version;$scope++) { - my $vkeys=$hash{"$scope:keys:$rid"}; - my @keys=split(/:/,$vkeys); - my $key; - $qresult.="$scope:keys=$vkeys&"; - foreach $key (@keys) { - $qresult.="$scope:$key=".$hash{"$scope:$rid:$key"}."&"; - } - } - if (untie(%hash)) { - $qresult=~s/\&$//; - Reply( $client, "$qresult\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting restore\n", $userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting restore\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; # Only used for logging purposes. + + my ($cmd,$udom,$uname,$namespace,$rid) = split(/:/,$userinput); + $namespace=~s/\//\_/g; + $namespace=~s/\W//g; + chomp($rid); + my $proname=propath($udom,$uname); + my $qresult=''; + my %hash; + if (tie(%hash,'GDBM_File',"$proname/$namespace.db", + &GDBM_READER(),0640)) { + my $version=$hash{"version:$rid"}; + $qresult.="version=$version&"; + my $scope; + for ($scope=1;$scope<=$version;$scope++) { + my $vkeys=$hash{"$scope:keys:$rid"}; + my @keys=split(/:/,$vkeys); + my $key; + $qresult.="$scope:keys=$vkeys&"; + foreach $key (@keys) { + $qresult.="$scope:$key=".$hash{"$scope:$rid:$key"}."&"; + } + } + if (untie(%hash)) { + $qresult=~s/\&$//; + Reply( $client, "$qresult\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting restore\n", $userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting restore\n", $userinput); + } - return 1; + return 1; } @@ -2051,17 +2050,17 @@ RegisterHandler("restor", \&RestoreHandl # # sub SendChatHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; - my ($cdom,$cnum,$newpost)=split(/\:/,$tail); - &chatadd($cdom,$cnum,$newpost); - Reply($client, "ok\n", $userinput); + my ($cdom,$cnum,$newpost)=split(/\:/,$tail); + &chatadd($cdom,$cnum,$newpost); + Reply($client, "ok\n", $userinput); - return 1; + return 1; } RegisterHandler("chatsend", \&SendChatHandler, 0, 1, 0); # @@ -2082,22 +2081,22 @@ RegisterHandler("chatsend", \&SendChatHa # Response is written to the client. # sub RetrieveChatHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($cdom,$cnum,$udom,$uname)=split(/\:/,$tail); - my $reply=''; - foreach (&getchat($cdom,$cnum,$udom,$uname)) { - $reply.=&escape($_).':'; - } - $reply=~s/\:$//; - Reply($client, $reply."\n", $userinput); + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($cdom,$cnum,$udom,$uname)=split(/\:/,$tail); + my $reply=''; + foreach (&getchat($cdom,$cnum,$udom,$uname)) { + $reply.=&escape($_).':'; + } + $reply=~s/\:$//; + Reply($client, $reply."\n", $userinput); - return 1; + return 1; } RegisterHandler("chatretr", \&RetrieveChatHandler, 0, 1, 0); # @@ -2120,19 +2119,19 @@ RegisterHandler("chatretr", \&RetrieveCh # a reply is written to $client. # sub SendQueryHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($query,$arg1,$arg2,$arg3)=split(/\:/,$tail); - $query=~s/\n*$//g; - Reply($client, "". sqlreply("$clientname\&$query". - "\&$arg1"."\&$arg2"."\&$arg3")."\n", - $userinput); - - return 1; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($query,$arg1,$arg2,$arg3)=split(/\:/,$tail); + $query=~s/\n*$//g; + Reply($client, "". sqlreply("$clientname\&$query". + "\&$arg1"."\&$arg2"."\&$arg3")."\n", + $userinput); + + return 1; } RegisterHandler("querysend", \&SendQueryHandler, 0, 1, 0); @@ -2162,32 +2161,31 @@ RegisterHandler("querysend", \&SendQuery # ok written to the client. # sub ReplyQueryHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($cmd,$id,$reply)=split(/:/,$userinput); - my $store; - my $execdir=$perlvar{'lonDaemons'}; - if ($store=IO::File->new(">$execdir/tmp/$id")) { - $reply=~s/\&/\n/g; - print $store $reply; - close $store; - my $store2=IO::File->new(">$execdir/tmp/$id.end"); - print $store2 "done\n"; - close $store2; - Reply($client, "ok\n", $userinput); - } - else { - Failure($client, "error: ".($!+0) - ." IO::File->new Failed ". - "while attempting queryreply\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($cmd,$id,$reply)=split(/:/,$userinput); + my $store; + my $execdir=$perlvar{'lonDaemons'}; + if ($store=IO::File->new(">$execdir/tmp/$id")) { + $reply=~s/\&/\n/g; + print $store $reply; + close $store; + my $store2=IO::File->new(">$execdir/tmp/$id.end"); + print $store2 "done\n"; + close $store2; + Reply($client, "ok\n", $userinput); + } else { + Failure($client, "error: ".($!+0) + ." IO::File->new Failed ". + "while attempting queryreply\n", $userinput); + } - return 1; + return 1; } RegisterHandler("queryreply", \&ReplyQueryHandler, 0, 1, 0); # @@ -2209,39 +2207,39 @@ RegisterHandler("queryreply", \&ReplyQue # reply is written to the client. # sub PutCourseIdHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($udom,$what)=split(/:/,$tail); - chomp($what); - $udom=~s/\W//g; - my $proname= - "$perlvar{'lonUsersDir'}/$udom/nohist_courseids"; - my $now=time; - my @pairs=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) { - foreach my $pair (@pairs) { - my ($key,$value)=split(/=/,$pair); - $hash{$key}=$value.':'.$now; - } - if (untie(%hash)) { - Reply($client, "ok\n", $userinput); - } else { - Failure( $client, "error: ".($!+0) - ." untie(GDBM) Failed ". - "while attempting courseidput\n", $userinput); - } - } else { - Failure( $client, "error: ".($!+0) - ." tie(GDBM) Failed ". - "while attempting courseidput\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; - return 1; + my $userinput = "$cmd:$tail"; + + my ($udom,$what)=split(/:/,$tail); + chomp($what); + $udom=~s/\W//g; + my $proname= + "$perlvar{'lonUsersDir'}/$udom/nohist_courseids"; + my $now=time; + my @pairs=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) { + foreach my $pair (@pairs) { + my ($key,$value)=split(/=/,$pair); + $hash{$key}=$value.':'.$now; + } + if (untie(%hash)) { + Reply($client, "ok\n", $userinput); + } else { + Failure( $client, "error: ".($!+0) + ." untie(GDBM) Failed ". + "while attempting courseidput\n", $userinput); + } + } else { + Failure( $client, "error: ".($!+0) + ." tie(GDBM) Failed ". + "while attempting courseidput\n", $userinput); + } + + return 1; } RegisterHandler("courseidput", \&PutCourseIdHandler, 0, 1, 0); @@ -2269,51 +2267,51 @@ RegisterHandler("courseidput", \&PutCour # Side Effects: # a reply is written to $client. sub DumpCourseIdHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($udom,$since,$description) =split(/:/,$tail); - if (defined($description)) { - $description=&unescape($description); - } else { - $description='.'; - } - unless (defined($since)) { $since=0; } - my $qresult=''; - my $proname = "$perlvar{'lonUsersDir'}/$udom/nohist_courseids"; - my %hash; - if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) { - while (my ($key,$value) = each(%hash)) { - my ($descr,$lasttime)=split(/\:/,$value); - if ($lasttime<$since) { - next; - } - if ($description eq '.') { - $qresult.=$key.'='.$descr.'&'; - } else { - my $unescapeVal = &unescape($descr); - if (eval('$unescapeVal=~/$description/i')) { - $qresult.="$key=$descr&"; - } - } - } - if (untie(%hash)) { - chop($qresult); - Reply($client, "$qresult\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting courseiddump\n", $userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting courseiddump\n", $userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($udom,$since,$description) =split(/:/,$tail); + if (defined($description)) { + $description=&unescape($description); + } else { + $description='.'; + } + unless (defined($since)) { $since=0; } + my $qresult=''; + my $proname = "$perlvar{'lonUsersDir'}/$udom/nohist_courseids"; + my %hash; + if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) { + while (my ($key,$value) = each(%hash)) { + my ($descr,$lasttime)=split(/\:/,$value); + if ($lasttime<$since) { + next; + } + if ($description eq '.') { + $qresult.=$key.'='.$descr.'&'; + } else { + my $unescapeVal = &unescape($descr); + if (eval('$unescapeVal=~/$description/i')) { + $qresult.="$key=$descr&"; + } + } + } + if (untie(%hash)) { + chop($qresult); + Reply($client, "$qresult\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting courseiddump\n", $userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting courseiddump\n", $userinput); + } - return 1; + return 1; } RegisterHandler("courseiddump", \&DumpCourseIdHandler, 0, 1, 0); # @@ -2333,42 +2331,42 @@ RegisterHandler("courseiddump", \&DumpCo # reply is written to $client. # sub PutIdHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - my ($udom,$what)=split(/:/,$tail); - chomp($what); - $udom=~s/\W//g; - my $proname="$perlvar{'lonUsersDir'}/$udom/ids"; - my $now=time; - { - my $hfh; - if ($hfh=IO::File->new(">>$proname.hist")) { - print $hfh "P:$now:$what\n"; + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + my ($udom,$what)=split(/:/,$tail); + chomp($what); + $udom=~s/\W//g; + my $proname="$perlvar{'lonUsersDir'}/$udom/ids"; + my $now=time; + { + my $hfh; + if ($hfh=IO::File->new(">>$proname.hist")) { + print $hfh "P:$now:$what\n"; + } + } + my @pairs=split(/\&/,$what); + my %hash; + if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) { + foreach my $pair (@pairs) { + my ($key,$value)=split(/=/,$pair); + $hash{$key}=$value; + } + if (untie(%hash)) { + Reply($client, "ok\n", $userinput); + } else { + Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting idput\n", $userinput); + } + } else { + Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting idput\n", $userinput); } - } - my @pairs=split(/\&/,$what); - my %hash; - if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) { - foreach my $pair (@pairs) { - my ($key,$value)=split(/=/,$pair); - $hash{$key}=$value; - } - if (untie(%hash)) { - Reply($client, "ok\n", $userinput); - } else { - Failure($client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting idput\n", $userinput); - } - } else { - Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting idput\n", $userinput); - } - return 1; + return 1; } RegisterHandler("idput", \&PutIdHandler, 0, 1, 0); @@ -2392,36 +2390,36 @@ RegisterHandler("idput", \&PutIdHandler, # An & separated list of results is written to $client. # sub GetIdHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$client:$tail"; - - my ($udom,$what)=split(/:/,$tail); - chomp($what); - $udom=~s/\W//g; - my $proname="$perlvar{'lonUsersDir'}/$udom/ids"; - my @queries=split(/\&/,$what); - my $qresult=''; - my %hash; - if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) { - for (my $i=0;$i<=$#queries;$i++) { - $qresult.="$hash{$queries[$i]}&"; - } - if (untie(%hash)) { - $qresult=~s/\&$//; - Reply($client, "$qresult\n", $userinput); - } else { - Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". - "while attempting idget\n",$userinput); - } - } else { - Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". - "while attempting idget\n",$userinput); - } + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$client:$tail"; + + my ($udom,$what)=split(/:/,$tail); + chomp($what); + $udom=~s/\W//g; + my $proname="$perlvar{'lonUsersDir'}/$udom/ids"; + my @queries=split(/\&/,$what); + my $qresult=''; + my %hash; + if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) { + for (my $i=0;$i<=$#queries;$i++) { + $qresult.="$hash{$queries[$i]}&"; + } + if (untie(%hash)) { + $qresult=~s/\&$//; + Reply($client, "$qresult\n", $userinput); + } else { + Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ". + "while attempting idget\n",$userinput); + } + } else { + Failure($client, "error: ".($!+0)." tie(GDBM) Failed ". + "while attempting idget\n",$userinput); + } - return 1; + return 1; } RegisterHandler("idget", \&GetIdHandler, 0, 1, 0); @@ -2443,29 +2441,28 @@ RegisterHandler("idget", \&GetIdHandler, # A file is created in the local filesystem. # A reply is sent to the client. sub TmpPutHandler { - my $cmd = shift; - my $what = shift; - my $client = shift; - - my $userinput = "$cmd:$what"; # Reconstruct for logging. - - - my $store; - $tmpsnum++; - my $id=$$.'_'.$clientip.'_'.$tmpsnum; - $id=~s/\W/\_/g; - $what=~s/\n//g; - my $execdir=$perlvar{'lonDaemons'}; - if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) { - print $store $what; - close $store; - Reply($client, "$id\n", $userinput); - } - else { - Failure( $client, "error: ".($!+0)."IO::File->new Failed ". - "while attempting tmpput\n", $userinput); - } - return 1; + my $cmd = shift; + my $what = shift; + my $client = shift; + + my $userinput = "$cmd:$what"; # Reconstruct for logging. + + + my $store; + $tmpsnum++; + my $id=$$.'_'.$clientip.'_'.$tmpsnum; + $id=~s/\W/\_/g; + $what=~s/\n//g; + my $execdir=$perlvar{'lonDaemons'}; + if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) { + print $store $what; + close $store; + Reply($client, "$id\n", $userinput); + } else { + Failure( $client, "error: ".($!+0)."IO::File->new Failed ". + "while attempting tmpput\n", $userinput); + } + return 1; } RegisterHandler("tmpput", \&TmpPutHandler, 0, 1, 0); @@ -2485,26 +2482,25 @@ RegisterHandler("tmpput", \&TmpPutHandle # sub TmpGetHandler { - my $cmd = shift; - my $id = shift; - my $client = shift; - my $userinput = "$cmd:$id"; - - chomp($id); - $id=~s/\W/\_/g; - my $store; - my $execdir=$perlvar{'lonDaemons'}; - if ($store=IO::File->new("$execdir/tmp/$id.tmp")) { - my $reply=<$store>; - Reply( $client, "$reply\n", $userinput); - close $store; - } - else { - Failure( $client, "error: ".($!+0)."IO::File->new Failed ". - "while attempting tmpget\n", $userinput); - } + my $cmd = shift; + my $id = shift; + my $client = shift; + my $userinput = "$cmd:$id"; + + chomp($id); + $id=~s/\W/\_/g; + my $store; + my $execdir=$perlvar{'lonDaemons'}; + if ($store=IO::File->new("$execdir/tmp/$id.tmp")) { + my $reply=<$store>; + Reply( $client, "$reply\n", $userinput); + close $store; + } else { + Failure( $client, "error: ".($!+0)."IO::File->new Failed ". + "while attempting tmpget\n", $userinput); + } - return 1; + return 1; } RegisterHandler("tmpget", \&TmpGetHandler, 0, 1, 0); # @@ -2522,23 +2518,23 @@ RegisterHandler("tmpget", \&TmpGetHandle # A file is deleted # A reply is sent to the client. sub TmpDelHandler { - my $cmd = shift; - my $id = shift; - my $client = shift; - - my $userinput= "$cmd:$id"; - - chomp($id); - $id=~s/\W/\_/g; - my $execdir=$perlvar{'lonDaemons'}; - if (unlink("$execdir/tmp/$id.tmp")) { - Reply($client, "ok\n", $userinput); - } else { - Failure( $client, "error: ".($!+0)."Unlink tmp Failed ". - "while attempting tmpdel\n", $userinput); - } + my $cmd = shift; + my $id = shift; + my $client = shift; + + my $userinput= "$cmd:$id"; - return 1; + chomp($id); + $id=~s/\W/\_/g; + my $execdir=$perlvar{'lonDaemons'}; + if (unlink("$execdir/tmp/$id.tmp")) { + Reply($client, "ok\n", $userinput); + } else { + Failure( $client, "error: ".($!+0)."Unlink tmp Failed ". + "while attempting tmpdel\n", $userinput); + } + + return 1; } RegisterHandler("tmpdel", \&TmpDelHandler, 0, 1, 0); @@ -2559,36 +2555,36 @@ RegisterHandler("tmpdel", \&TmpDelHandle # The reply is written to $client. # sub LsHandler { - my $cmd = shift; - my $ulsdir = shift; - my $client = shift; - - my $userinput = "$cmd:$ulsdir"; - - my $ulsout=''; - my $ulsfn; - if (-e $ulsdir) { - if(-d $ulsdir) { - if (opendir(LSDIR,$ulsdir)) { - while ($ulsfn=readdir(LSDIR)) { - my @ulsstats=stat($ulsdir.'/'.$ulsfn); - $ulsout.=$ulsfn.'&'. - join('&',@ulsstats).':'; - } - 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); + my $cmd = shift; + my $ulsdir = shift; + my $client = shift; + my $userinput = "$cmd:$ulsdir"; - return 1; + my $ulsout=''; + my $ulsfn; + if (-e $ulsdir) { + if(-d $ulsdir) { + if (opendir(LSDIR,$ulsdir)) { + while ($ulsfn=readdir(LSDIR)) { + my @ulsstats=stat($ulsdir.'/'.$ulsfn); + $ulsout.=$ulsfn.'&'. + join('&',@ulsstats).':'; + } + 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); + + + return 1; } RegisterHandler("ls", \&LsHandler, 0, 1, 0); @@ -2613,24 +2609,24 @@ RegisterHandler("ls", \&LsHandler, 0, 1, # A reply is sent to $client. # sub SetAnnounceHandler { - my $cmd = shift; - my $announcement = shift; - my $client = shift; + my $cmd = shift; + my $announcement = shift; + my $client = shift; - my $userinput = "$cmd:$announcement"; + my $userinput = "$cmd:$announcement"; - chomp($announcement); - $announcement=&unescape($announcement); - if (my $store=IO::File->new('>'.$perlvar{'lonDocRoot'}. - '/announcement.txt')) { - print $store $announcement; - close $store; - Reply($client, "ok\n", $userinput); - } else { - Failure($client, "error: ".($!+0)."\n", $userinput); - } + chomp($announcement); + $announcement=&unescape($announcement); + if (my $store=IO::File->new('>'.$perlvar{'lonDocRoot'}. + '/announcement.txt')) { + print $store $announcement; + close $store; + Reply($client, "ok\n", $userinput); + } else { + Failure($client, "error: ".($!+0)."\n", $userinput); + } - return 1; + return 1; } RegisterHandler("setannounce", \&SetAnnounceHandler, 0, 1, 0); @@ -2648,15 +2644,15 @@ RegisterHandler("setannounce", \&SetAnno # Side Effects: # Replies with version to $client. sub GetVersionHandler { - my $client = shift; - my $tail = shift; - my $client = shift; - my $userinput = $client; - - Reply($client, &version($userinput)."\n", $userinput); + my $client = shift; + my $tail = shift; + my $client = shift; + my $userinput = $client; + + Reply($client, &version($userinput)."\n", $userinput); - return 1; + return 1; } RegisterHandler("version", \&GetVersionHandler, 0, 1, 0); @@ -2678,16 +2674,16 @@ RegisterHandler("version", \&GetVersionH # a reply is sent to the client. # sub SelectHostHandler { - my $cmd = shift; - my $tail = shift; - my $socket = shift; + my $cmd = shift; + my $tail = shift; + my $socket = shift; - my $userinput ="$cmd:$tail"; + my $userinput ="$cmd:$tail"; - Reply($client, &sethost($userinput)."\n", $userinput); + Reply($client, &sethost($userinput)."\n", $userinput); - return 1; + return 1; } RegisterHandler("sethost", \&SelectHostHandler, 0, 1, 0); @@ -2703,18 +2699,18 @@ RegisterHandler("sethost", \&SelectHostH # 0 - Indicating the program should exit!! # sub ExitHandler { - my $cmd = shift; - my $tail = shift; - my $client = shift; - - my $userinput = "$cmd:$tail"; - - &logthis("Client $clientip ($clientname) hanging up: $userinput"); - Reply($client, "bye\n", $userinput); - $client->shutdown(2); # shutdown the socket forcibly. - $client->close(); + my $cmd = shift; + my $tail = shift; + my $client = shift; + + my $userinput = "$cmd:$tail"; + + &logthis("Client $clientip ($clientname) hanging up: $userinput"); + Reply($client, "bye\n", $userinput); + $client->shutdown(2); # shutdown the socket forcibly. + $client->close(); - return 0; + return 0; } RegisterHandler("exit", \&ExitHandler, 0, 1,1); RegisterHandler("init", \&ExitHandler, 0, 1,1); # RE-init is like exit. @@ -2732,77 +2728,77 @@ RegisterHandler("quit", \&ExitHandler, 0 # 1 - Accept additional requests from the client. # sub ProcessRequest { - my $Request = shift; - my $KeepGoing = 1; # Assume we're not asked to stop. + my $Request = shift; + my $KeepGoing = 1; # Assume we're not asked to stop. - my $wasenc=0; - my $userinput = $Request; # for compatibility with oldcode + my $wasenc=0; + my $userinput = $Request; # for compatibility with oldcode # ------------------------------------------------------------ See if encrypted - if($userinput =~ /^enc/) { - $wasenc = 1; - $userinput = Decipher($userinput); - if(! $userinput) { - Failure($client,"error:Encrypted data without negotiating key"); - return 0; # Break off with this imposter. - } - } - # Split off the request keyword from the rest of the stuff. + if($userinput =~ /^enc/) { + $wasenc = 1; + $userinput = Decipher($userinput); + if(! $userinput) { + Failure($client,"error:Encrypted data without negotiating key"); + return 0; # Break off with this imposter. + } + } + # Split off the request keyword from the rest of the stuff. - my ($command, $tail) = split(/:/, $userinput, 2); + my ($command, $tail) = split(/:/, $userinput, 2); - Debug("Command received: $command, encoded = $wasenc"); + Debug("Command received: $command, encoded = $wasenc"); # ------------------------------------------------------------- Normal commands - # - # If the command is in the hash, then execute it via the hash dispatch: - # - if(defined $Dispatcher{$command}) { - - my $DispatchInfo = $Dispatcher{$command}; - my $Handler = $$DispatchInfo[0]; - my $NeedEncode = $$DispatchInfo[1]; - my $ClientTypes = $$DispatchInfo[2]; - Debug("Matched dispatch hash: mustencode: $NeedEncode ClientType $ClientTypes"); + # + # If the command is in the hash, then execute it via the hash dispatch: + # + if(defined $Dispatcher{$command}) { + + my $DispatchInfo = $Dispatcher{$command}; + my $Handler = $$DispatchInfo[0]; + my $NeedEncode = $$DispatchInfo[1]; + my $ClientTypes = $$DispatchInfo[2]; + Debug("Matched dispatch hash: mustencode: $NeedEncode ClientType $ClientTypes"); - # Validate the request: + # Validate the request: - my $ok = 1; - my $requesterprivs = 0; - if(isClient()) { - $requesterprivs |= $CLIENT_OK; - } - if(isManager()) { - $requesterprivs |= $MANAGER_OK; - } - if($NeedEncode && (!$wasenc)) { - Debug("Must encode but wasn't: $NeedEncode $wasenc"); - $ok = 0; - } - if(($ClientTypes & $requesterprivs) == 0) { - Debug("Client not privileged to do this operation"); - $ok = 0; - } - - if($ok) { - Debug("Dispatching to handler $command $tail"); - $KeepGoing = &$Handler($command, $tail, $client); - } else { - Debug("Refusing to dispatch because ok is false"); - Failure($client, "refused", $userinput); - } + my $ok = 1; + my $requesterprivs = 0; + if(isClient()) { + $requesterprivs |= $CLIENT_OK; + } + if(isManager()) { + $requesterprivs |= $MANAGER_OK; + } + if($NeedEncode && (!$wasenc)) { + Debug("Must encode but wasn't: $NeedEncode $wasenc"); + $ok = 0; + } + if(($ClientTypes & $requesterprivs) == 0) { + Debug("Client not privileged to do this operation"); + $ok = 0; + } + + if($ok) { + Debug("Dispatching to handler $command $tail"); + $KeepGoing = &$Handler($command, $tail, $client); + } else { + Debug("Refusing to dispatch because ok is false"); + Failure($client, "refused", $userinput); + } # ------------------------------------------------------------- unknown command - } else { + } else { # unknown command - Failure($client, "unknown_cmd\n", $userinput); - } + Failure($client, "unknown_cmd\n", $userinput); + } return $KeepGoing; } @@ -2839,42 +2835,42 @@ sub ReadManagerTable { # Clean out the old table first.. - foreach my $key (keys %managers) { - delete $managers{$key}; - } - - my $tablename = $perlvar{'lonTabDir'}."/managers.tab"; - if (!open (MANAGERS, $tablename)) { - logthis('No manager table. Nobody can manage!!'); - return; - } - while(my $host = ) { - chomp($host); - if ($host =~ "^#") { # Comment line. - logthis(' Skipping line: '. "$host\n"); - next; - } - if (!defined $hostip{$host}) { # This is a non cluster member + foreach my $key (keys %managers) { + delete $managers{$key}; + } + + my $tablename = $perlvar{'lonTabDir'}."/managers.tab"; + if (!open (MANAGERS, $tablename)) { + logthis('No manager table. Nobody can manage!!'); + return; + } + while(my $host = ) { + chomp($host); + if ($host =~ "^#") { # Comment line. + logthis(' Skipping line: '. "$host\n"); + next; + } + if (!defined $hostip{$host}) { # This is a non cluster member # The entry is of the form: # cluname:hostname # cluname - A 'cluster hostname' is needed in order to negotiate # the host key. # hostname- The dns name of the host. # - my($cluname, $dnsname) = split(/:/, $host); - - my $ip = gethostbyname($dnsname); - if(defined($ip)) { # bad names don't deserve entry. - my $hostip = inet_ntoa($ip); - $managers{$hostip} = $cluname; - logthis(' registering manager '. - "$dnsname as $cluname with $hostip \n"); - } - } else { - logthis(' existing host'." $host\n"); - $managers{$hostip{$host}} = $host; # Use info from cluster tab if clumemeber - } - } + my($cluname, $dnsname) = split(/:/, $host); + + my $ip = gethostbyname($dnsname); + if(defined($ip)) { # bad names don't deserve entry. + my $hostip = inet_ntoa($ip); + $managers{$hostip} = $cluname; + logthis(' registering manager '. + "$dnsname as $cluname with $hostip \n"); + } + } else { + logthis(' existing host'." $host\n"); + $managers{$hostip{$host}} = $host; # Use info from cluster tab if clumemeber + } + } } # @@ -2908,7 +2904,7 @@ sub CopyFile { if(-e $oldfile) { - # Read the old file. + # Read the old file. my $oldfh = IO::File->new("< $oldfile"); if(!$oldfh) { @@ -2961,30 +2957,30 @@ sub AdjustHostContents { my $adjusted; my $me = $perlvar{'lonHostID'}; - foreach my $line (split(/\n/,$contents)) { + foreach my $line (split(/\n/,$contents)) { if(!(($line eq "") || ($line =~ /^ *\#/) || ($line =~ /^ *$/))) { chomp($line); my ($id,$domain,$role,$name,$ip,$maxcon,$idleto,$mincon)=split(/:/,$line); if ($id eq $me) { - my $ip = gethostbyname($name); - my $ipnew = inet_ntoa($ip); - $ip = $ipnew; + my $ip = gethostbyname($name); + my $ipnew = inet_ntoa($ip); + $ip = $ipnew; # Reconstruct the host line and append to adjusted: - my $newline = "$id:$domain:$role:$name:$ip"; - if($maxcon ne "") { # Not all hosts have loncnew tuning params - $newline .= ":$maxcon:$idleto:$mincon"; - } - $adjusted .= $newline."\n"; + my $newline = "$id:$domain:$role:$name:$ip"; + if($maxcon ne "") { # Not all hosts have loncnew tuning params + $newline .= ":$maxcon:$idleto:$mincon"; + } + $adjusted .= $newline."\n"; - } else { # Not me, pass unmodified. - $adjusted .= $line."\n"; - } + } else { # Not me, pass unmodified. + $adjusted .= $line."\n"; + } } else { # Blank or comment never re-written. $adjusted .= $line."\n"; # Pass blanks and comments as is. } - } - return $adjusted; + } + return $adjusted; } # # InstallFile: Called to install an administrative file: @@ -3007,14 +3003,14 @@ sub InstallFile { my $TempFile = $Filename.".tmp"; # Open the file for write: - + my $fh = IO::File->new("> $TempFile"); # Write to temp. if(!(defined $fh)) { &logthis(' Unable to create '.$TempFile.""); return 0; } # write the contents of the file: - + print $fh ($Contents); $fh->close; # In case we ever have a filesystem w. locking @@ -3097,7 +3093,7 @@ sub PushFile { return "error:$!"; } &logthis(' Pushfile: backed up ' - .$tablefile." to $backupfile"); + .$tablefile." to $backupfile"); # If the file being pushed is the host file, we adjust the entry for ourself so that the # IP will be our current IP as looked up in dns. Note this is only 99% good as it's possible @@ -3113,13 +3109,12 @@ sub PushFile { if(!InstallFile($tablefile, $contents)) { &logthis(' Pushfile: unable to install ' - .$tablefile." $! "); + .$tablefile." $! "); return "error:$!"; - } - else { + } else { &logthis(' Installed new '.$tablefile .""); - + } @@ -3256,7 +3251,7 @@ sub ApplyEdit { } elsif ($command eq "delete") { $editor->DeleteLine($p1); # p1 - key p2 null. } else { # Should not get here!!! - die "Invalid command given to ApplyEdit $command" + die "Invalid command given to ApplyEdit $command"; } } # @@ -3426,8 +3421,8 @@ sub catchexception { $SIG{__DIE__}='DEFAULT'; &status("Catching exception"); &logthis("CRITICAL: " - ."ABNORMAL EXIT. Child $$ for server $thisserver died through " - ."a crash with this error msg->[$error]"); + ."ABNORMAL EXIT. Child $$ for server $thisserver died through " + ."a crash with this error msg->[$error]"); &logthis('Famous last words: '.$status.' - '.$lastlog); if ($client) { print $client "error: $error\n"; } $server->close(); @@ -3453,11 +3448,11 @@ undef $perlvarref; # ----------------------------- Make sure this process is running from user=www my $wwwid=getpwnam('www'); if ($wwwid!=$<) { - my $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}"; - my $subj="LON: $currenthostid User ID mismatch"; - system("echo 'User ID mismatch. lond must be run as user www.' |\ + my $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}"; + my $subj="LON: $currenthostid User ID mismatch"; + system("echo 'User ID mismatch. lond must be run as user www.' |\ mailto $emailto -s '$subj' > /dev/null"); - exit 1; + exit 1; } # --------------------------------------------- Check if other instance running @@ -3465,10 +3460,10 @@ if ($wwwid!=$<) { my $pidfile="$perlvar{'lonDaemons'}/logs/lond.pid"; if (-e $pidfile) { - my $lfh=IO::File->new("$pidfile"); - my $pide=<$lfh>; - chomp($pide); - if (kill 0 => $pide) { die "already running"; } + my $lfh=IO::File->new("$pidfile"); + my $pide=<$lfh>; + chomp($pide); + if (kill 0 => $pide) { die "already running"; } } # ------------------------------------------------------------- Read hosts file @@ -3481,7 +3476,7 @@ $server = IO::Socket::INET->new(LocalPor Proto => 'tcp', Reuse => 1, Listen => 10 ) - or die "making socket: $@\n"; + or die "making socket: $@\n"; # --------------------------------------------------------- Do global variables @@ -3634,17 +3629,17 @@ sub checkchildren { &status("Checking on the children (waiting for reports)"); foreach (sort keys %children) { unless (-e "$docdir/lon-status/londchld/$_.txt") { - eval { - alarm(300); - &logthis('Child '.$_.' did not respond'); - kill 9 => $_; - #$emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}"; - #$subj="LON: $currenthostid killed lond process $_"; - #my $result=`echo 'Killed lond process $_.' | mailto $emailto -s '$subj' > /dev/null`; - #$execdir=$perlvar{'lonDaemons'}; - #$result=`/bin/cp $execdir/logs/lond.log $execdir/logs/lond.log.$_`; - alarm(0); - } + eval { + alarm(300); + &logthis('Child '.$_.' did not respond'); + kill 9 => $_; + #$emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}"; + #$subj="LON: $currenthostid killed lond process $_"; + #my $result=`echo 'Killed lond process $_.' | mailto $emailto -s '$subj' > /dev/null`; + #$execdir=$perlvar{'lonDaemons'}; + #$result=`/bin/cp $execdir/logs/lond.log $execdir/logs/lond.log.$_`; + alarm(0); + } } } $SIG{ALRM} = 'DEFAULT'; @@ -3712,31 +3707,31 @@ sub Reply { # client: # sub Failure { - my $fd = shift; - my $reply = shift; - my $request = shift; + my $fd = shift; + my $reply = shift; + my $request = shift; - $Failures++; - Reply($fd, $reply, $request); # That's simple eh? + $Failures++; + Reply($fd, $reply, $request); # That's simple eh? } # ------------------------------------------------------------------ Log status sub logstatus { - &status("Doing logging"); - my $docdir=$perlvar{'lonDocRoot'}; - { - my $fh=IO::File->new(">>$docdir/lon-status/londstatus.txt"); - print $fh $$."\t".$currenthostid."\t".$status."\t".$lastlog."\n"; - $fh->close(); - } - &status("Finished londstatus.txt"); - { - my $fh=IO::File->new(">$docdir/lon-status/londchld/$$.txt"); - print $fh $status."\n".$lastlog."\n".time; - $fh->close(); - } - ResetStatistics; - &status("Finished logging"); + &status("Doing logging"); + my $docdir=$perlvar{'lonDocRoot'}; + { + my $fh=IO::File->new(">>$docdir/lon-status/londstatus.txt"); + print $fh $$."\t".$currenthostid."\t".$status."\t".$lastlog."\n"; + $fh->close(); + } + &status("Finished londstatus.txt"); + { + my $fh=IO::File->new(">$docdir/lon-status/londchld/$$.txt"); + print $fh $status."\n".$lastlog."\n".time; + $fh->close(); + } + ResetStatistics; + &status("Finished logging"); } @@ -3761,7 +3756,7 @@ sub status { my $local=localtime($now); my $status = "lond: $what $local "; if($Transactions) { - $status .= " Transactions: $Transactions Failed; $Failures"; + $status .= " Transactions: $Transactions Failed; $Failures"; } $0=$status; } @@ -3795,12 +3790,11 @@ sub reconlonc { &logthis("lonc at pid $loncpid responding, sending USR1"); kill USR1 => $loncpid; } else { - &logthis( - "CRITICAL: " - ."lonc at pid $loncpid not responding, giving up"); + &logthis("CRITICAL: " + ."lonc at pid $loncpid not responding, giving up"); } } else { - &logthis('CRITICAL: lonc not running, giving up'); + &logthis('CRITICAL: lonc not running, giving up'); } } @@ -3812,7 +3806,7 @@ sub subreply { my $sclient=IO::Socket::UNIX->new(Peer =>"$peerfile", Type => SOCK_STREAM, Timeout => 10) - or return "con_lost"; + or return "con_lost"; print $sclient "$cmd\n"; my $answer=<$sclient>; chomp($answer); @@ -3821,22 +3815,22 @@ sub subreply { } sub reply { - my ($cmd,$server)=@_; - my $answer; - if ($server ne $currenthostid) { - $answer=subreply($cmd,$server); - if ($answer eq 'con_lost') { - $answer=subreply("ping",$server); - if ($answer ne $server) { - &logthis("sub reply: answer != server answer is $answer, server is $server"); - &reconlonc("$perlvar{'lonSockDir'}/$server"); - } - $answer=subreply($cmd,$server); - } - } else { - $answer='self_reply'; - } - return $answer; + my ($cmd,$server)=@_; + my $answer; + if ($server ne $currenthostid) { + $answer=subreply($cmd,$server); + if ($answer eq 'con_lost') { + $answer=subreply("ping",$server); + if ($answer ne $server) { + &logthis("sub reply: answer != server answer is $answer, server is $server"); + &reconlonc("$perlvar{'lonSockDir'}/$server"); + } + $answer=subreply($cmd,$server); + } + } else { + $answer='self_reply'; + } + return $answer; } # -------------------------------------------------------------- Talk to lonsql @@ -3855,7 +3849,7 @@ sub subsqlreply { my $sclient=IO::Socket::UNIX->new(Peer =>"$peerfile", Type => SOCK_STREAM, Timeout => 10) - or return "con_lost"; + or return "con_lost"; print $sclient "$cmd\n"; my $answer=<$sclient>; chomp($answer); @@ -3948,7 +3942,7 @@ sub make_new_child { $sigset = POSIX::SigSet->new(SIGINT); sigprocmask(SIG_BLOCK, $sigset) or die "Can't block SIGINT for fork: $!\n"; - + die "fork: $!" unless defined ($pid = fork); $client->sockopt(SO_KEEPALIVE, 1); # Enable monitoring of @@ -3988,7 +3982,7 @@ sub make_new_child { &Authen::Krb5::init_context(); &Authen::Krb5::init_ets(); - + &status('Accepted connection'); # ============================================================================= # do something with the connection @@ -4015,7 +4009,7 @@ sub make_new_child { &status("Waiting for init from $clientip $clientname"); &logthis('INFO: Connection, '. $clientip. - " ($clientname) connection type = $ConnectionType " ); + " ($clientname) connection type = $ConnectionType " ); &status("Connecting $clientip ($clientname))"); my $remotereq=<$client>; $remotereq=~s/[^\w:]//g; @@ -4023,27 +4017,23 @@ sub make_new_child { &sethost("sethost:$perlvar{'lonHostID'}"); my $challenge="$$".time; print $client "$challenge\n"; - &status( - "Waiting for challenge reply from $clientip ($clientname)"); + &status("Waiting for challenge reply from $clientip ($clientname)"); $remotereq=<$client>; $remotereq=~s/\W//g; if ($challenge eq $remotereq) { $clientok=1; print $client "ok\n"; } else { - &logthis( - "WARNING: $clientip did not reply challenge"); + &logthis("WARNING: $clientip did not reply challenge"); &status('No challenge reply '.$clientip); } } else { - &logthis( - "WARNING: " + &logthis("WARNING: " ."$clientip failed to initialize: >$remotereq< "); &status('No init '.$clientip); } } else { - &logthis( - "WARNING: Unknown client $clientip"); + &logthis("WARNING: Unknown client $clientip"); &status('Hung up on '.$clientip); } if ($clientok) { @@ -4104,8 +4094,7 @@ sub make_new_child { # user - Name of the user for which the role is being put. # authtype - The authentication type associated with the user. # -sub ManagePermissions -{ +sub ManagePermissions { my $request = shift; my $domain = shift; my $user = shift; @@ -4125,8 +4114,7 @@ sub ManagePermissions # Returns the authorization type or nouser if there is no such user. # -sub GetAuthType -{ +sub GetAuthType { my $domain = shift; my $user = shift; @@ -4146,8 +4134,7 @@ sub GetAuthType } return "$authtype:$availinfo"; - } - else { + } else { Debug("Returning nouser"); return "nouser"; } @@ -4256,7 +4243,7 @@ sub currentversion { my $version=-1; my $ulsdir=''; if ($fname=~/^(.+)\/[^\/]+$/) { - $ulsdir=$1; + $ulsdir=$1; } my ($fnamere1,$fnamere2); # remove version if already specified @@ -4313,8 +4300,8 @@ sub subscribe { symlink($root.'.'.$extension, $root.'.'.$currentversion.'.'.$extension); unless ($extension=~/\.meta$/) { - symlink($root.'.'.$extension.'.meta', - $root.'.'.$currentversion.'.'.$extension.'.meta'); + symlink($root.'.'.$extension.'.meta', + $root.'.'.$currentversion.'.'.$extension.'.meta'); } } }