Diff for /loncom/lond between versions 1.160 and 1.161

version 1.160, 2003/11/01 16:32:32 version 1.161, 2003/11/11 12:39:14
Line 24 Line 24
 #  #
 # /home/httpd/html/adm/gpl.txt  # /home/httpd/html/adm/gpl.txt
 #  #
   
   
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
   
Line 57  my $currentdomainid; Line 59  my $currentdomainid;
   
 my $client;  my $client;
 my $clientip;  my $clientip;
   my $clientname;
   
 my $server;  my $server;
 my $thisserver;  my $thisserver;
   
   # 
   #   Connection type is:
   #      client                   - All client actions are allowed
   #      manager                  - only management functions allowed.
   #      both                     - Both management and client actions are allowed
   #
   
   my $ConnectionType;
   
 my %hostid;  my %hostid;
 my %hostdom;  my %hostdom;
 my %hostip;  my %hostip;
 my %managers; # If defined $managers{hostname} is a manager  
   my %managers; # Ip -> manager names
   
 my %perlvar; # Will have the apache conf defined perl vars.  my %perlvar; # Will have the apache conf defined perl vars.
   
 #  #
Line 121  sub GetCertificate { Line 135  sub GetCertificate {
   
     return $clientip;      return $clientip;
 }  }
   
   #
   #   Return true if client is a manager.
   #
   sub isManager {
       return (($ConnectionType eq "manager") || ($ConnectionType eq "both"));
   }
   #
   #   Return tru if client can do client functions
   #
   sub isClient {
       return (($ConnectionType eq "client") || ($ConnectionType eq "both"));
   }
   
   
 #  #
 #   ReadManagerTable: Reads in the current manager table. For now this is  #   ReadManagerTable: Reads in the current manager table. For now this is
 #                     done on each manager authentication because:  #                     done on each manager authentication because:
Line 144  sub ReadManagerTable { Line 173  sub ReadManagerTable {
     }      }
     while(my $host = <MANAGERS>) {      while(my $host = <MANAGERS>) {
  chomp($host);   chomp($host);
  if (!defined $hostip{$host}) {   if (!defined $hostip{$host}) { # This is a non cluster member
     logthis('<font color="red"> manager '.$host.  
     " not in hosts.tab, rejected as manager</font>");      #  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);
       open(MGRPIPE, "/usr/bin/host $dnsname |") || die "Can't make host pipeline";
       my $dnsinfo = <MGRPIPE>;
       chomp $dnsinfo;
       close MGRPIPE;
       my($jname, $jhas, $jaddress, $hostip) = split(/ /, $dnsinfo);
       $managers{$hostip} = $cluname;
  } else {   } else {
     $managers{$host} = $hostip{$host}; # Whatever for now.      $managers{$hostip{$host}} = $host;  # Use info from cluster tab if clumemeber
  }   }
     }      }
 }  }
Line 724  sub Debug { Line 766  sub Debug {
  &logthis($message);   &logthis($message);
     }      }
 }  }
   
   #
   #   Sub to do replies to client.. this gives a hook for some
   #   debug tracing too:
   #  Parameters:
   #     fd      - File open on client.
   #     reply   - Text to send to client.
   #     request - Original request from client.
   #
   sub Reply {
       my $fd      = shift;
       my $reply   = shift;
       my $request = shift;
   
       print $fd $reply;
       Debug("Request was $request  Reply was $reply");
   
   }
 # ------------------------------------------------------------------ Log status  # ------------------------------------------------------------------ Log status
   
 sub logstatus {  sub logstatus {
Line 935  sub make_new_child { Line 995  sub make_new_child {
     my $sigset;      my $sigset;
   
     $client = shift;      $client = shift;
     &logthis("Attempting to start child");          &logthis('<font color="green"> Attempting to start child ('.$client.
        ")</font>");    
     # block signal for fork      # block signal for fork
     $sigset = POSIX::SigSet->new(SIGINT);      $sigset = POSIX::SigSet->new(SIGINT);
     sigprocmask(SIG_BLOCK, $sigset)      sigprocmask(SIG_BLOCK, $sigset)
Line 981  sub make_new_child { Line 1042  sub make_new_child {
         &Authen::Krb5::init_context();          &Authen::Krb5::init_context();
         &Authen::Krb5::init_ets();          &Authen::Krb5::init_ets();
   
             &status('Accepted connection');   &status('Accepted connection');
 # =============================================================================  # =============================================================================
             # do something with the connection              # do something with the connection
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
  # see if we know client and check for spoof IP by challenge   # see if we know client and check for spoof IP by challenge
   
             my $clientrec=($hostid{$clientip} ne undef);   ReadManagerTable; # May also be a manager!!
             &logthis(  
 "<font color=yellow>INFO: Connection, $clientip ($hostid{$clientip})</font>"   my $clientrec=($hostid{$clientip}     ne undef);
             );   my $ismanager=($managers{$clientip}    ne undef);
             &status("Connecting $clientip ($hostid{$clientip})");    $clientname  = "[unknonwn]";
             my $clientok;   if($clientrec) { # Establish client type.
             if ($clientrec) {      $ConnectionType = "client";
       &status("Waiting for init from $clientip ($hostid{$clientip})");      $clientname = $hostid{$clientip};
       my $remotereq=<$client>;      if($ismanager) {
               $remotereq=~s/[^\w:]//g;   $ConnectionType = "both";
               if ($remotereq =~ /^init/) {      }
   &sethost("sethost:$perlvar{'lonHostID'}");   } else {
   my $challenge="$$".time;      $ConnectionType = "manager";
                   print $client "$challenge\n";      $clientname = $managers{$clientip};
                   &status(   }
            "Waiting for challenge reply from $clientip ($hostid{$clientip})");    my $clientok;
                   $remotereq=<$client>;   if ($clientrec || $ismanager) {
                   $remotereq=~s/\W//g;      &status("Waiting for init from $clientip $clientname");
                   if ($challenge eq $remotereq) {      &logthis('<font color="yellow">INFO: Connection, '.
       $clientok=1;       $clientip.
                       print $client "ok\n";    " ($clientname) connection type = $ConnectionType </font>" );
                   } else {      &status("Connecting $clientip  ($clientname))"); 
       &logthis(      my $remotereq=<$client>;
  "<font color=blue>WARNING: $clientip did not reply challenge</font>");      $remotereq=~s/[^\w:]//g;
                       &status('No challenge reply '.$clientip);      if ($remotereq =~ /^init/) {
                   }   &sethost("sethost:$perlvar{'lonHostID'}");
               } else {   my $challenge="$$".time;
   &logthis(   print $client "$challenge\n";
                     "<font color=blue>WARNING: "   &status(
                    ."$clientip failed to initialize: >$remotereq< </font>");   "Waiting for challenge reply from $clientip ($clientname)"); 
                   &status('No init '.$clientip);   $remotereq=<$client>;
               }   $remotereq=~s/\W//g;
    if ($challenge eq $remotereq) {
       $clientok=1;
       print $client "ok\n";
    } else {
       &logthis(
        "<font color=blue>WARNING: $clientip did not reply challenge</font>");
       &status('No challenge reply '.$clientip);
    }
     } else {      } else {
               &logthis(   &logthis(
  "<font color=blue>WARNING: Unknown client $clientip</font>");   "<font color=blue>WARNING: "
               &status('Hung up on '.$clientip);   ."$clientip failed to initialize: >$remotereq< </font>");
             }   &status('No init '.$clientip);
             if ($clientok) {      }
    } else {
       &logthis(
        "<font color=blue>WARNING: Unknown client $clientip</font>");
       &status('Hung up on '.$clientip);
    }
    if ($clientok) {
 # ---------------- New known client connecting, could mean machine online again  # ---------------- New known client connecting, could mean machine online again
       
  foreach my $id (keys(%hostip)) {      foreach my $id (keys(%hostip)) {
     if ($hostip{$id} ne $clientip ||   if ($hostip{$id} ne $clientip ||
        $hostip{$currenthostid} eq $clientip) {      $hostip{$currenthostid} eq $clientip) {
  # no need to try to do recon's to myself      # no need to try to do recon's to myself
  next;      next;
     }  
     &reconlonc("$perlvar{'lonSockDir'}/$id");  
  }   }
  &logthis("<font color=green>Established connection: $hostid{$clientip}</font>");   &reconlonc("$perlvar{'lonSockDir'}/$id");
               &status('Will listen to '.$hostid{$clientip});      }
       &logthis("<font color=green>Established connection: $clientname</font>");
       &status('Will listen to '.$clientname);
 # ------------------------------------------------------------ Process requests  # ------------------------------------------------------------ Process requests
               while (my $userinput=<$client>) {      while (my $userinput=<$client>) {
                 chomp($userinput);                  chomp($userinput);
  Debug("Request = $userinput\n");   Debug("Request = $userinput\n");
                 &status('Processing '.$hostid{$clientip}.': '.$userinput);                  &status('Processing '.$clientname.': '.$userinput);
                 my $wasenc=0;                  my $wasenc=0;
                 alarm(120);                  alarm(120);
 # ------------------------------------------------------------ See if encrypted  # ------------------------------------------------------------ See if encrypted
  if ($userinput =~ /^enc/) {   if ($userinput =~ /^enc/) {
   if ($cipher) {      if ($cipher) {
                     my ($cmd,$cmdlength,$encinput)=split(/:/,$userinput);   my ($cmd,$cmdlength,$encinput)=split(/:/,$userinput);
     $userinput='';   $userinput='';
                     for (my $encidx=0;$encidx<length($encinput);$encidx+=16) {   for (my $encidx=0;$encidx<length($encinput);$encidx+=16) {
                        $userinput.=      $userinput.=
    $cipher->decrypt(   $cipher->decrypt(
                             pack("H16",substr($encinput,$encidx,16))   pack("H16",substr($encinput,$encidx,16))
                            );   );
    }
    $userinput=substr($userinput,0,$cmdlength);
    $wasenc=1;
     }      }
     $userinput=substr($userinput,0,$cmdlength);  
                     $wasenc=1;  
  }   }
       }  
     
 # ------------------------------------------------------------- Normal commands  # ------------------------------------------------------------- Normal commands
 # ------------------------------------------------------------------------ ping  # ------------------------------------------------------------------------ ping
    if ($userinput =~ /^ping/) {   if ($userinput =~ /^ping/) { # client only
                        print $client "$currenthostid\n";      if(isClient) {
    print $client "$currenthostid\n";
       } else {
    Reply($client, "refused\n", $userinput);
       }
 # ------------------------------------------------------------------------ pong  # ------------------------------------------------------------------------ pong
    }elsif ($userinput =~ /^pong/) {   }elsif ($userinput =~ /^pong/) { # client only
                        my $reply=&reply("ping",$hostid{$clientip});      if(isClient) {
                        print $client "$currenthostid:$reply\n";    my $reply=&reply("ping",$clientname);
    print $client "$currenthostid:$reply\n"; 
       } else {
    Reply($client, "refused\n", $userinput);
       }
 # ------------------------------------------------------------------------ ekey  # ------------------------------------------------------------------------ ekey
    } elsif ($userinput =~ /^ekey/) {   } elsif ($userinput =~ /^ekey/) { # ok for both clients & mgrs
                        my $buildkey=time.$$.int(rand 100000);      my $buildkey=time.$$.int(rand 100000);
                        $buildkey=~tr/1-6/A-F/;      $buildkey=~tr/1-6/A-F/;
                        $buildkey=int(rand 100000).$buildkey.int(rand 100000);      $buildkey=int(rand 100000).$buildkey.int(rand 100000);
                        my $key=$currenthostid.$hostid{$clientip};      my $key=$currenthostid.$clientname;
                        $key=~tr/a-z/A-Z/;      $key=~tr/a-z/A-Z/;
                        $key=~tr/G-P/0-9/;      $key=~tr/G-P/0-9/;
                        $key=~tr/Q-Z/0-9/;      $key=~tr/Q-Z/0-9/;
                        $key=$key.$buildkey.$key.$buildkey.$key.$buildkey;      $key=$key.$buildkey.$key.$buildkey.$key.$buildkey;
                        $key=substr($key,0,32);      $key=substr($key,0,32);
                        my $cipherkey=pack("H32",$key);      my $cipherkey=pack("H32",$key);
                        $cipher=new IDEA $cipherkey;      $cipher=new IDEA $cipherkey;
                        print $client "$buildkey\n";       print $client "$buildkey\n"; 
 # ------------------------------------------------------------------------ load  # ------------------------------------------------------------------------ load
    } elsif ($userinput =~ /^load/) {   } elsif ($userinput =~ /^load/) { # client only
                        my $loadavg;      if (isClient) {
                        {   my $loadavg;
                           my $loadfile=IO::File->new('/proc/loadavg');   {
                           $loadavg=<$loadfile>;      my $loadfile=IO::File->new('/proc/loadavg');
                        }      $loadavg=<$loadfile>;
                        $loadavg =~ s/\s.*//g;   }
        my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'};   $loadavg =~ s/\s.*//g;
        print $client "$loadpercent\n";   my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'};
    print $client "$loadpercent\n";
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # -------------------------------------------------------------------- userload  # -------------------------------------------------------------------- userload
    } elsif ($userinput =~ /^userload/) {   } elsif ($userinput =~ /^userload/) { # client only
        my $userloadpercent=&userload();      if(isClient) {
        print $client "$userloadpercent\n";   my $userloadpercent=&userload();
    print $client "$userloadpercent\n";
       } else {
    Reply($client, "refused\n", $userinput);
        
       }
 #  #
 #        Transactions requiring encryption:  #        Transactions requiring encryption:
 #  #
 # ----------------------------------------------------------------- currentauth  # ----------------------------------------------------------------- currentauth
    } elsif ($userinput =~ /^currentauth/) {   } elsif ($userinput =~ /^currentauth/) {
      if ($wasenc==1) {      if (($wasenc==1)  && isClient) { # Encoded & client only.
                        my ($cmd,$udom,$uname)=split(/:/,$userinput);   my ($cmd,$udom,$uname)=split(/:/,$userinput);
        my $result = GetAuthType($udom, $uname);   my $result = GetAuthType($udom, $uname);
        if($result eq "nouser") {   if($result eq "nouser") {
    print $client "unknown_user\n";      print $client "unknown_user\n";
        }   }
        else {   else {
    print $client "$result\n"      print $client "$result\n"
        }      }
      } else {      } else {
        print $client "refused\n";   Reply($client, "refused\n", $userinput);
      }  
       }
 #--------------------------------------------------------------------- pushfile  #--------------------------------------------------------------------- pushfile
    } elsif($userinput =~ /^pushfile/) {    } elsif($userinput =~ /^pushfile/) { # encoded & manager.
        if($wasenc == 1) {      if(($wasenc == 1) && isManager) {
    my $cert = GetCertificate($userinput);   my $cert = GetCertificate($userinput);
    if(ValidManager($cert)) {   if(ValidManager($cert)) {
        my $reply = PushFile($userinput);      my $reply = PushFile($userinput);
        print $client "$reply\n";      print $client "$reply\n";
    } else {   } else {
        print $client "refused\n";      print $client "refused\n";
    }    } 
        } else {      } else {
    print $client "refused\n";   Reply($client, "refused\n", $userinput);
        }  
       }
 #--------------------------------------------------------------------- reinit  #--------------------------------------------------------------------- reinit
    } elsif($userinput =~ /^reinit/) {   } elsif($userinput =~ /^reinit/) { # Encoded and manager
        if ($wasenc == 1) {      if (($wasenc == 1) && isManager) {
    my $cert = GetCertificate($userinput);   my $cert = GetCertificate($userinput);
    if(ValidManager($cert)) {   if(ValidManager($cert)) {
        chomp($userinput);      chomp($userinput);
        my $reply = ReinitProcess($userinput);      my $reply = ReinitProcess($userinput);
        print $client  "$reply\n";      print $client  "$reply\n";
    } else {   } else {
        print $client "refused\n";      print $client "refused\n";
    }   }
        } else {      } else {
    print $client "refused\n";   Reply($client, "refused\n", $userinput);
        }  
   
       }
 # ------------------------------------------------------------------------ auth  # ------------------------------------------------------------------------ auth
                    } elsif ($userinput =~ /^auth/) {   } elsif ($userinput =~ /^auth/) { # Encoded and client only.
      if ($wasenc==1) {      if (($wasenc==1) && isClient) {
                        my ($cmd,$udom,$uname,$upass)=split(/:/,$userinput);   my ($cmd,$udom,$uname,$upass)=split(/:/,$userinput);
                        chomp($upass);   chomp($upass);
                        $upass=unescape($upass);   $upass=unescape($upass);
                        my $proname=propath($udom,$uname);   my $proname=propath($udom,$uname);
                        my $passfilename="$proname/passwd";   my $passfilename="$proname/passwd";
                        if (-e $passfilename) {   if (-e $passfilename) {
                           my $pf = IO::File->new($passfilename);      my $pf = IO::File->new($passfilename);
                           my $realpasswd=<$pf>;      my $realpasswd=<$pf>;
                           chomp($realpasswd);      chomp($realpasswd);
                           my ($howpwd,$contentpwd)=split(/:/,$realpasswd);      my ($howpwd,$contentpwd)=split(/:/,$realpasswd);
                           my $pwdcorrect=0;      my $pwdcorrect=0;
                           if ($howpwd eq 'internal') {      if ($howpwd eq 'internal') {
       &Debug("Internal auth");   &Debug("Internal auth");
       $pwdcorrect=   $pwdcorrect=
   (crypt($upass,$contentpwd) eq $contentpwd);      (crypt($upass,$contentpwd) eq $contentpwd);
                           } elsif ($howpwd eq 'unix') {      } elsif ($howpwd eq 'unix') {
       &Debug("Unix auth");   &Debug("Unix auth");
                               if((getpwnam($uname))[1] eq "") { #no such user!   if((getpwnam($uname))[1] eq "") { #no such user!
   $pwdcorrect = 0;      $pwdcorrect = 0;
       } else {   } else {
   $contentpwd=(getpwnam($uname))[1];      $contentpwd=(getpwnam($uname))[1];
   my $pwauth_path="/usr/local/sbin/pwauth";      my $pwauth_path="/usr/local/sbin/pwauth";
   unless ($contentpwd eq 'x') {      unless ($contentpwd eq 'x') {
       $pwdcorrect=   $pwdcorrect=
   (crypt($upass,$contentpwd) eq       (crypt($upass,$contentpwd) eq 
    $contentpwd);       $contentpwd);
   }      }
         
       elsif (-e $pwauth_path) {      elsif (-e $pwauth_path) {
   open PWAUTH, "|$pwauth_path" or   open PWAUTH, "|$pwauth_path" or
       die "Cannot invoke authentication";      die "Cannot invoke authentication";
   print PWAUTH "$uname\n$upass\n";   print PWAUTH "$uname\n$upass\n";
   close PWAUTH;   close PWAUTH;
   $pwdcorrect=!$?;   $pwdcorrect=!$?;
       }      }
       }   }
                           } elsif ($howpwd eq 'krb4') {      } elsif ($howpwd eq 'krb4') {
                               my $null=pack("C",0);   my $null=pack("C",0);
                               unless ($upass=~/$null/) {   unless ($upass=~/$null/) {
                                   my $krb4_error = &Authen::Krb4::get_pw_in_tkt      my $krb4_error = &Authen::Krb4::get_pw_in_tkt
                                       ($uname,"",$contentpwd,'krbtgt',   ($uname,"",$contentpwd,'krbtgt',
                                        $contentpwd,1,$upass);   $contentpwd,1,$upass);
                                   if (!$krb4_error) {      if (!$krb4_error) {
                                       $pwdcorrect = 1;   $pwdcorrect = 1;
                                   } else {       } else { 
                                       $pwdcorrect=0;    $pwdcorrect=0; 
                                       # log error if it is not a bad password   # log error if it is not a bad password
                                       if ($krb4_error != 62) {   if ($krb4_error != 62) {
        &logthis('krb4:'.$uname.','.$contentpwd.','.      &logthis('krb4:'.$uname.','.$contentpwd.','.
                 &Authen::Krb4::get_err_txt($Authen::Krb4::error));       &Authen::Krb4::get_err_txt($Authen::Krb4::error));
                                       }   }
                                   }      }
                               }   }
                           } elsif ($howpwd eq 'krb5') {      } elsif ($howpwd eq 'krb5') {
       my $null=pack("C",0);   my $null=pack("C",0);
       unless ($upass=~/$null/) {   unless ($upass=~/$null/) {
   my $krbclient=&Authen::Krb5::parse_name($uname.'@'.$contentpwd);      my $krbclient=&Authen::Krb5::parse_name($uname.'@'.$contentpwd);
   my $krbservice="krbtgt/".$contentpwd."\@".$contentpwd;      my $krbservice="krbtgt/".$contentpwd."\@".$contentpwd;
   my $krbserver=&Authen::Krb5::parse_name($krbservice);      my $krbserver=&Authen::Krb5::parse_name($krbservice);
   my $credentials=&Authen::Krb5::cc_default();      my $credentials=&Authen::Krb5::cc_default();
   $credentials->initialize($krbclient);      $credentials->initialize($krbclient);
   my $krbreturn =       my $krbreturn = 
     &Authen::Krb5::get_in_tkt_with_password(   &Authen::Krb5::get_in_tkt_with_password(
      $krbclient,$krbserver,$upass,$credentials);   $krbclient,$krbserver,$upass,$credentials);
 #  unless ($krbreturn) {  #  unless ($krbreturn) {
 #      &logthis("Krb5 Error: ".  #      &logthis("Krb5 Error: ".
 #       &Authen::Krb5::error());  #       &Authen::Krb5::error());
 #  }  #  }
   $pwdcorrect = ($krbreturn == 1);      $pwdcorrect = ($krbreturn == 1);
    } else { $pwdcorrect=0; }   } else { $pwdcorrect=0; }
                           } elsif ($howpwd eq 'localauth') {      } elsif ($howpwd eq 'localauth') {
     $pwdcorrect=&localauth::localauth($uname,$upass,   $pwdcorrect=&localauth::localauth($uname,$upass,
       $contentpwd);    $contentpwd);
   }      }
                           if ($pwdcorrect) {      if ($pwdcorrect) {
                              print $client "authorized\n";   print $client "authorized\n";
                           } else {      } else {
                              print $client "non_authorized\n";   print $client "non_authorized\n";
                           }        }  
        } else {   } else {
                           print $client "unknown_user\n";      print $client "unknown_user\n";
                        }   }
      } else {      } else {
        print $client "refused\n";   Reply($client, "refused\n", $userinput);
      }         
       }
 # ---------------------------------------------------------------------- passwd  # ---------------------------------------------------------------------- passwd
                    } elsif ($userinput =~ /^passwd/) {   } elsif ($userinput =~ /^passwd/) { # encoded and client
      if ($wasenc==1) {      if (($wasenc==1) && isClient) {
                        my    my 
                        ($cmd,$udom,$uname,$upass,$npass)=split(/:/,$userinput);      ($cmd,$udom,$uname,$upass,$npass)=split(/:/,$userinput);
                        chomp($npass);   chomp($npass);
                        $upass=&unescape($upass);   $upass=&unescape($upass);
                        $npass=&unescape($npass);   $npass=&unescape($npass);
        &Debug("Trying to change password for $uname");   &Debug("Trying to change password for $uname");
        my $proname=propath($udom,$uname);   my $proname=propath($udom,$uname);
                        my $passfilename="$proname/passwd";   my $passfilename="$proname/passwd";
                        if (-e $passfilename) {   if (-e $passfilename) {
    my $realpasswd;      my $realpasswd;
                           { my $pf = IO::File->new($passfilename);      { my $pf = IO::File->new($passfilename);
     $realpasswd=<$pf>; }        $realpasswd=<$pf>; }
                           chomp($realpasswd);      chomp($realpasswd);
                           my ($howpwd,$contentpwd)=split(/:/,$realpasswd);      my ($howpwd,$contentpwd)=split(/:/,$realpasswd);
                           if ($howpwd eq 'internal') {      if ($howpwd eq 'internal') {
    &Debug("internal auth");   &Debug("internal auth");
    if (crypt($upass,$contentpwd) eq $contentpwd) {   if (crypt($upass,$contentpwd) eq $contentpwd) {
      my $salt=time;      my $salt=time;
                              $salt=substr($salt,6,2);      $salt=substr($salt,6,2);
      my $ncpass=crypt($npass,$salt);      my $ncpass=crypt($npass,$salt);
                              {      {
  my $pf;   my $pf;
  if ($pf = IO::File->new(">$passfilename")) {   if ($pf = IO::File->new(">$passfilename")) {
      print $pf "internal:$ncpass\n";      print $pf "internal:$ncpass\n";
      &logthis("Result of password change for $uname: pwchange_success");      &logthis("Result of password change for $uname: pwchange_success");
      print $client "ok\n";      print $client "ok\n";
  } else {   } else {
      &logthis("Unable to open $uname passwd to change password");      &logthis("Unable to open $uname passwd to change password");
      print $client "non_authorized\n";      print $client "non_authorized\n";
  }   }
      }                   }             
            
                            } else {   } else {
                              print $client "non_authorized\n";      print $client "non_authorized\n";
                            }   }
                           } elsif ($howpwd eq 'unix') {      } elsif ($howpwd eq 'unix') {
       # Unix means we have to access /etc/password   # Unix means we have to access /etc/password
       # one way or another.   # one way or another.
       # First: Make sure the current password is   # First: Make sure the current password is
       #        correct   #        correct
       &Debug("auth is unix");   &Debug("auth is unix");
       $contentpwd=(getpwnam($uname))[1];   $contentpwd=(getpwnam($uname))[1];
       my $pwdcorrect = "0";   my $pwdcorrect = "0";
       my $pwauth_path="/usr/local/sbin/pwauth";   my $pwauth_path="/usr/local/sbin/pwauth";
       unless ($contentpwd eq 'x') {   unless ($contentpwd eq 'x') {
   $pwdcorrect=      $pwdcorrect=
                                     (crypt($upass,$contentpwd) eq $contentpwd);   (crypt($upass,$contentpwd) eq $contentpwd);
       } elsif (-e $pwauth_path) {   } elsif (-e $pwauth_path) {
   open PWAUTH, "|$pwauth_path" or      open PWAUTH, "|$pwauth_path" or
       die "Cannot invoke authentication";   die "Cannot invoke authentication";
   print PWAUTH "$uname\n$upass\n";      print PWAUTH "$uname\n$upass\n";
   close PWAUTH;      close PWAUTH;
   &Debug("exited pwauth with $? ($uname,$upass) ");      &Debug("exited pwauth with $? ($uname,$upass) ");
   $pwdcorrect=($? == 0);      $pwdcorrect=($? == 0);
       }   }
      if ($pwdcorrect) {   if ($pwdcorrect) {
  my $execdir=$perlvar{'lonDaemons'};      my $execdir=$perlvar{'lonDaemons'};
  &Debug("Opening lcpasswd pipeline");      &Debug("Opening lcpasswd pipeline");
  my $pf = IO::File->new("|$execdir/lcpasswd > $perlvar{'lonDaemons'}/logs/lcpasswd.log");      my $pf = IO::File->new("|$execdir/lcpasswd > $perlvar{'lonDaemons'}/logs/lcpasswd.log");
  print $pf "$uname\n$npass\n$npass\n";      print $pf "$uname\n$npass\n$npass\n";
  close $pf;      close $pf;
  my $err = $?;      my $err = $?;
  my $result = ($err>0 ? 'pwchange_failure'       my $result = ($err>0 ? 'pwchange_failure' 
        : 'ok');    : 'ok');
  &logthis("Result of password change for $uname: ".      &logthis("Result of password change for $uname: ".
   &lcpasswdstrerror($?));       &lcpasswdstrerror($?));
  print $client "$result\n";      print $client "$result\n";
      } else {   } else {
  print $client "non_authorized\n";      print $client "non_authorized\n";
      }   }
   } else {      } else {
                             print $client "auth_mode_error\n";   print $client "auth_mode_error\n";
                           }        }  
        } else {   } else {
                           print $client "unknown_user\n";      print $client "unknown_user\n";
                        }   }
      } else {      } else {
        print $client "refused\n";   Reply($client, "refused\n", $userinput);
      }         
       }
 # -------------------------------------------------------------------- makeuser  # -------------------------------------------------------------------- makeuser
                    } elsif ($userinput =~ /^makeuser/) {   } elsif ($userinput =~ /^makeuser/) { # encoded and client.
      &Debug("Make user received");      &Debug("Make user received");
                 my $oldumask=umask(0077);      my $oldumask=umask(0077);
      if ($wasenc==1) {      if (($wasenc==1) && isClient) {
                        my    my 
                        ($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput);      ($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput);
        &Debug("cmd =".$cmd." $udom =".$udom.   &Debug("cmd =".$cmd." $udom =".$udom.
     " uname=".$uname);         " uname=".$uname);
                        chomp($npass);   chomp($npass);
                        $npass=&unescape($npass);   $npass=&unescape($npass);
                        my $proname=propath($udom,$uname);   my $proname=propath($udom,$uname);
                        my $passfilename="$proname/passwd";   my $passfilename="$proname/passwd";
        &Debug("Password file created will be:".   &Debug("Password file created will be:".
     $passfilename);         $passfilename);
                        if (-e $passfilename) {   if (-e $passfilename) {
    print $client "already_exists\n";      print $client "already_exists\n";
                        } elsif ($udom ne $currentdomainid) {   } elsif ($udom ne $currentdomainid) {
                            print $client "not_right_domain\n";      print $client "not_right_domain\n";
                        } else {   } else {
                            my @fpparts=split(/\//,$proname);      my @fpparts=split(/\//,$proname);
                            my $fpnow=$fpparts[0].'/'.$fpparts[1].'/'.$fpparts[2];      my $fpnow=$fpparts[0].'/'.$fpparts[1].'/'.$fpparts[2];
                            my $fperror='';      my $fperror='';
                            for (my $i=3;$i<=$#fpparts;$i++) {      for (my $i=3;$i<=$#fpparts;$i++) {
                                $fpnow.='/'.$fpparts[$i];    $fpnow.='/'.$fpparts[$i]; 
                                unless (-e $fpnow) {   unless (-e $fpnow) {
    unless (mkdir($fpnow,0777)) {      unless (mkdir($fpnow,0777)) {
                                       $fperror="error: ".($!+0)   $fperror="error: ".($!+0)
   ." mkdir failed while attempting "      ." mkdir failed while attempting "
                                               ."makeuser\n";      ."makeuser\n";
                                    }      }
                                }   }
                            }      }
                            unless ($fperror) {      unless ($fperror) {
        my $result=&make_passwd_file($uname, $umode,$npass,   my $result=&make_passwd_file($uname, $umode,$npass,
     $passfilename);       $passfilename);
        print $client $result;   print $client $result;
                            } else {      } else {
                                print $client "$fperror\n";   print $client "$fperror\n";
                            }      }
                        }   }
      } else {      } else {
        print $client "refused\n";   Reply($client, "refused\n", $userinput);
      }        
      umask($oldumask);      }
       umask($oldumask);
 # -------------------------------------------------------------- changeuserauth  # -------------------------------------------------------------- changeuserauth
                    } elsif ($userinput =~ /^changeuserauth/) {   } elsif ($userinput =~ /^changeuserauth/) { # encoded & client
        &Debug("Changing authorization");      &Debug("Changing authorization");
       if ($wasenc==1) {      if (($wasenc==1) && isClient) {
                        my    my 
        ($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput);      ($cmd,$udom,$uname,$umode,$npass)=split(/:/,$userinput);
                        chomp($npass);   chomp($npass);
        &Debug("cmd = ".$cmd." domain= ".$udom.   &Debug("cmd = ".$cmd." domain= ".$udom.
       "uname =".$uname." umode= ".$umode);         "uname =".$uname." umode= ".$umode);
                        $npass=&unescape($npass);   $npass=&unescape($npass);
                        my $proname=&propath($udom,$uname);   my $proname=&propath($udom,$uname);
                        my $passfilename="$proname/passwd";   my $passfilename="$proname/passwd";
        if ($udom ne $currentdomainid) {   if ($udom ne $currentdomainid) {
                            print $client "not_right_domain\n";      print $client "not_right_domain\n";
                        } else {   } else {
    my $result=&make_passwd_file($uname, $umode,$npass,      my $result=&make_passwd_file($uname, $umode,$npass,
  $passfilename);   $passfilename);
    print $client $result;      print $client $result;
                        }   }
      } else {      } else {
        print $client "refused\n";   Reply($client, "refused\n", $userinput);
      }     
       }
 # ------------------------------------------------------------------------ home  # ------------------------------------------------------------------------ home
                    } elsif ($userinput =~ /^home/) {   } elsif ($userinput =~ /^home/) { # client clear or encoded
                        my ($cmd,$udom,$uname)=split(/:/,$userinput);      if(isClient) {
                        chomp($uname);   my ($cmd,$udom,$uname)=split(/:/,$userinput);
                        my $proname=propath($udom,$uname);   chomp($uname);
                        if (-e $proname) {   my $proname=propath($udom,$uname);
                           print $client "found\n";   if (-e $proname) {
                        } else {      print $client "found\n";
   print $client "not_found\n";   } else {
                        }      print $client "not_found\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ---------------------------------------------------------------------- update  # ---------------------------------------------------------------------- update
                    } elsif ($userinput =~ /^update/) {   } elsif ($userinput =~ /^update/) { # client clear or encoded.
                        my ($cmd,$fname)=split(/:/,$userinput);      if(isClient) {
                        my $ownership=ishome($fname);   my ($cmd,$fname)=split(/:/,$userinput);
                        if ($ownership eq 'not_owner') {   my $ownership=ishome($fname);
                         if (-e $fname) {   if ($ownership eq 'not_owner') {
                           my ($dev,$ino,$mode,$nlink,      if (-e $fname) {
                               $uid,$gid,$rdev,$size,   my ($dev,$ino,$mode,$nlink,
                               $atime,$mtime,$ctime,      $uid,$gid,$rdev,$size,
                               $blksize,$blocks)=stat($fname);      $atime,$mtime,$ctime,
                           my $now=time;      $blksize,$blocks)=stat($fname);
                           my $since=$now-$atime;   my $now=time;
                           if ($since>$perlvar{'lonExpire'}) {   my $since=$now-$atime;
                               my $reply=   if ($since>$perlvar{'lonExpire'}) {
                                     &reply("unsub:$fname","$hostid{$clientip}");      my $reply=
                               unlink("$fname");   &reply("unsub:$fname","$clientname");
                           } else {      unlink("$fname");
      my $transname="$fname.in.transfer";   } else {
                              my $remoteurl=      my $transname="$fname.in.transfer";
                                     reply("sub:$fname","$hostid{$clientip}");      my $remoteurl=
                              my $response;   &reply("sub:$fname","$clientname");
                               {      my $response;
                              my $ua=new LWP::UserAgent;      {
                              my $request=new HTTP::Request('GET',"$remoteurl");   my $ua=new LWP::UserAgent;
                              $response=$ua->request($request,$transname);   my $request=new HTTP::Request('GET',"$remoteurl");
       }   $response=$ua->request($request,$transname);
                              if ($response->is_error()) {      }
  unlink($transname);      if ($response->is_error()) {
                                  my $message=$response->status_line;   unlink($transname);
                                  &logthis(   my $message=$response->status_line;
                                   "LWP GET: $message for $fname ($remoteurl)");   &logthis(
                              } else {   "LWP GET: $message for $fname ($remoteurl)");
                          if ($remoteurl!~/\.meta$/) {      } else {
                                   my $ua=new LWP::UserAgent;   if ($remoteurl!~/\.meta$/) {
                                   my $mrequest=      my $ua=new LWP::UserAgent;
                                    new HTTP::Request('GET',$remoteurl.'.meta');      my $mrequest=
                                   my $mresponse=   new HTTP::Request('GET',$remoteurl.'.meta');
                                    $ua->request($mrequest,$fname.'.meta');      my $mresponse=
                                   if ($mresponse->is_error()) {   $ua->request($mrequest,$fname.'.meta');
                     unlink($fname.'.meta');      if ($mresponse->is_error()) {
                                   }   unlink($fname.'.meta');
                          }      }
                                  rename($transname,$fname);   }
      }   rename($transname,$fname);
                           }      }
                           print $client "ok\n";   }
                         } else {   print $client "ok\n";
                           print $client "not_found\n";      } else {
                         }   print $client "not_found\n";
        } else {      }
  print $client "rejected\n";   } else {
                        }      print $client "rejected\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # -------------------------------------- fetch a user file from a remote server  # -------------------------------------- fetch a user file from a remote server
                    } elsif ($userinput =~ /^fetchuserfile/) {   } elsif ($userinput =~ /^fetchuserfile/) { # Client clear or enc.
        my ($cmd,$fname)=split(/:/,$userinput);      if(isClient) {
        my ($udom,$uname,$ufile)=split(/\//,$fname);   my ($cmd,$fname)=split(/:/,$userinput);
        my $udir=propath($udom,$uname).'/userfiles';   my ($udom,$uname,$ufile)=split(/\//,$fname);
        unless (-e $udir) { mkdir($udir,0770); }   my $udir=propath($udom,$uname).'/userfiles';
                        if (-e $udir) {   unless (-e $udir) { mkdir($udir,0770); }
    $ufile=~s/^[\.\~]+//;   if (-e $udir) {
    $ufile=~s/\///g;      $ufile=~s/^[\.\~]+//;
    my $destname=$udir.'/'.$ufile;      $ufile=~s/\///g;
    my $transname=$udir.'/'.$ufile.'.in.transit';      my $destname=$udir.'/'.$ufile;
    my $remoteurl='http://'.$clientip.'/userfiles/'.$fname;      my $transname=$udir.'/'.$ufile.'.in.transit';
    my $response;      my $remoteurl='http://'.$clientip.'/userfiles/'.$fname;
    {      my $response;
        my $ua=new LWP::UserAgent;      {
        my $request=new HTTP::Request('GET',"$remoteurl");   my $ua=new LWP::UserAgent;
        $response=$ua->request($request,$transname);   my $request=new HTTP::Request('GET',"$remoteurl");
    }   $response=$ua->request($request,$transname);
    if ($response->is_error()) {      }
        unlink($transname);      if ($response->is_error()) {
        my $message=$response->status_line;   unlink($transname);
        &logthis("LWP GET: $message for $fname ($remoteurl)");   my $message=$response->status_line;
        print $client "failed\n";   &logthis("LWP GET: $message for $fname ($remoteurl)");
    } else {   print $client "failed\n";
        if (!rename($transname,$destname)) {      } else {
    &logthis("Unable to move $transname to $destname");   if (!rename($transname,$destname)) {
    unlink($transname);      &logthis("Unable to move $transname to $destname");
    print $client "failed\n";      unlink($transname);
        } else {      print $client "failed\n";
    print $client "ok\n";   } else {
        }      print $client "ok\n";
    }   }
        } else {      }
    print $client "not_home\n";   } else {
        }      print $client "not_home\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ------------------------------------------ authenticate access to a user file  # ------------------------------------------ authenticate access to a user file
                    } elsif ($userinput =~ /^tokenauthuserfile/) {   } elsif ($userinput =~ /^tokenauthuserfile/) { # Client only
                        my ($cmd,$fname,$session)=split(/:/,$userinput);      if(isClient) {
                        chomp($session);   my ($cmd,$fname,$session)=split(/:/,$userinput);
                        my $reply='non_auth';   chomp($session);
                        if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'.   my $reply='non_auth';
  $session.'.id')) {   if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'.
    while (my $line=<ENVIN>) {   $session.'.id')) {
        if ($line=~/userfile\.$fname\=/) { $reply='ok'; }      while (my $line=<ENVIN>) {
    }   if ($line=~/userfile\.$fname\=/) { $reply='ok'; }
    close(ENVIN);      }
    print $client $reply."\n";      close(ENVIN);
        } else {      print $client $reply."\n";
    print $client "invalid_token\n";   } else {
                        }      print $client "invalid_token\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ----------------------------------------------------------------- unsubscribe  # ----------------------------------------------------------------- unsubscribe
                    } elsif ($userinput =~ /^unsub/) {   } elsif ($userinput =~ /^unsub/) {
                        my ($cmd,$fname)=split(/:/,$userinput);      if(isClient) {
                        if (-e $fname) {   my ($cmd,$fname)=split(/:/,$userinput);
    print $client &unsub($client,$fname,$clientip);   if (-e $fname) {
                        } else {      print $client &unsub($client,$fname,$clientip);
    print $client "not_found\n";   } else {
                        }      print $client "not_found\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ------------------------------------------------------------------- subscribe  # ------------------------------------------------------------------- subscribe
                    } elsif ($userinput =~ /^sub/) {   } elsif ($userinput =~ /^sub/) {
        print $client &subscribe($userinput,$clientip);      if(isClient) {
    print $client &subscribe($userinput,$clientip);
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ------------------------------------------------------------- current version  # ------------------------------------------------------------- current version
                    } elsif ($userinput =~ /^currentversion/) {   } elsif ($userinput =~ /^currentversion/) {
                        my ($cmd,$fname)=split(/:/,$userinput);      if(isClient) {
        print $client &currentversion($fname)."\n";   my ($cmd,$fname)=split(/:/,$userinput);
    print $client &currentversion($fname)."\n";
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ------------------------------------------------------------------------- log  # ------------------------------------------------------------------------- log
                    } elsif ($userinput =~ /^log/) {   } elsif ($userinput =~ /^log/) {
                        my ($cmd,$udom,$uname,$what)=split(/:/,$userinput);      if(isClient) {
                        chomp($what);   my ($cmd,$udom,$uname,$what)=split(/:/,$userinput);
                        my $proname=propath($udom,$uname);   chomp($what);
                        my $now=time;   my $proname=propath($udom,$uname);
                        {   my $now=time;
  my $hfh;   {
  if ($hfh=IO::File->new(">>$proname/activity.log")) {       my $hfh;
                             print $hfh "$now:$hostid{$clientip}:$what\n";      if ($hfh=IO::File->new(">>$proname/activity.log")) { 
                             print $client "ok\n";    print $hfh "$now:$clientname:$what\n";
  } else {   print $client "ok\n"; 
                             print $client "error: ".($!+0)      } else {
  ." IO::File->new Failed "   print $client "error: ".($!+0)
                                     ."while attempting log\n";      ." IO::File->new Failed "
         }      ."while attempting log\n";
        }      }
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ------------------------------------------------------------------------- put  # ------------------------------------------------------------------------- put
                    } elsif ($userinput =~ /^put/) {   } elsif ($userinput =~ /^put/) {
                       my ($cmd,$udom,$uname,$namespace,$what)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$what)
                       $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                       $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                       if ($namespace ne 'roles') {   $namespace=~s/\W//g;
                        chomp($what);   if ($namespace ne 'roles') {
                        my $proname=propath($udom,$uname);      chomp($what);
                        my $now=time;      my $proname=propath($udom,$uname);
                        unless ($namespace=~/^nohist\_/) {      my $now=time;
    my $hfh;      unless ($namespace=~/^nohist\_/) {
    if (   my $hfh;
                              $hfh=IO::File->new(">>$proname/$namespace.hist")   if (
        ) { print $hfh "P:$now:$what\n"; }      $hfh=IO::File->new(">>$proname/$namespace.hist")
        }      ) { print $hfh "P:$now:$what\n"; }
                        my @pairs=split(/\&/,$what);      }
        my %hash;      my @pairs=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {      my %hash;
                            foreach my $pair (@pairs) {      if (tie(%hash,'GDBM_File',
        my ($key,$value)=split(/=/,$pair);      "$proname/$namespace.db",
                                $hash{$key}=$value;      &GDBM_WRCREAT(),0640)) {
                            }   foreach my $pair (@pairs) {
    if (untie(%hash)) {      my ($key,$value)=split(/=/,$pair);
                               print $client "ok\n";      $hash{$key}=$value;
                            } else {   }
                               print $client "error: ".($!+0)   if (untie(%hash)) {
   ." untie(GDBM) failed ".      print $client "ok\n";
                                       "while attempting put\n";   } else {
                            }      print $client "error: ".($!+0)
                        } else {   ." untie(GDBM) failed ".
                            print $client "error: ".($!)   "while attempting put\n";
        ." tie(GDBM) Failed ".   }
                                    "while attempting put\n";      } else {
                        }   print $client "error: ".($!)
       } else {      ." tie(GDBM) Failed ".
                           print $client "refused\n";      "while attempting put\n";
                       }      }
    } else {
       print $client "refused\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # -------------------------------------------------------------------- rolesput  # -------------------------------------------------------------------- rolesput
                    } elsif ($userinput =~ /^rolesput/) {   } elsif ($userinput =~ /^rolesput/) {
        &Debug("rolesput");      if(isClient) {
     if ($wasenc==1) {   &Debug("rolesput");
                        my ($cmd,$exedom,$exeuser,$udom,$uname,$what)   if ($wasenc==1) {
                           =split(/:/,$userinput);      my ($cmd,$exedom,$exeuser,$udom,$uname,$what)
        &Debug("cmd = ".$cmd." exedom= ".$exedom.   =split(/:/,$userinput);
     "user = ".$exeuser." udom=".$udom.      &Debug("cmd = ".$cmd." exedom= ".$exedom.
     "what = ".$what);     "user = ".$exeuser." udom=".$udom.
                        my $namespace='roles';     "what = ".$what);
                        chomp($what);      my $namespace='roles';
                        my $proname=propath($udom,$uname);      chomp($what);
                        my $now=time;      my $proname=propath($udom,$uname);
                        {      my $now=time;
    my $hfh;      {
    if (   my $hfh;
                              $hfh=IO::File->new(">>$proname/$namespace.hist")   if (
        ) {       $hfh=IO::File->new(">>$proname/$namespace.hist")
                                   print $hfh "P:$now:$exedom:$exeuser:$what\n";      ) { 
                                  }      print $hfh "P:$now:$exedom:$exeuser:$what\n";
        }   }
                        my @pairs=split(/\&/,$what);      }
        my %hash;      my @pairs=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {      my %hash;
                            foreach my $pair (@pairs) {      if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
        my ($key,$value)=split(/=/,$pair);   foreach my $pair (@pairs) {
        &ManagePermissions($key, $udom, $uname,      my ($key,$value)=split(/=/,$pair);
   &GetAuthType( $udom,       &ManagePermissions($key, $udom, $uname,
  $uname));         &GetAuthType( $udom, 
                                $hash{$key}=$value;       $uname));
                            }      $hash{$key}=$value;
    if (untie(%hash)) {   }
                               print $client "ok\n";   if (untie(%hash)) {
                            } else {      print $client "ok\n";
                               print $client "error: ".($!+0)   } else {
   ." untie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting rolesput\n";   ." untie(GDBM) Failed ".
                            }   "while attempting rolesput\n";
                        } else {   }
                            print $client "error: ".($!+0)      } else {
        ." tie(GDBM) Failed ".   print $client "error: ".($!+0)
                                    "while attempting rolesput\n";      ." tie(GDBM) Failed ".
                        }      "while attempting rolesput\n";
       } else {      }
                           print $client "refused\n";   } else {
                       }      print $client "refused\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
     
       }
 # -------------------------------------------------------------------- rolesdel  # -------------------------------------------------------------------- rolesdel
                    } elsif ($userinput =~ /^rolesdel/) {   } elsif ($userinput =~ /^rolesdel/) {
        &Debug("rolesdel");      if(isClient) {
     if ($wasenc==1) {   &Debug("rolesdel");
                        my ($cmd,$exedom,$exeuser,$udom,$uname,$what)   if ($wasenc==1) {
                           =split(/:/,$userinput);      my ($cmd,$exedom,$exeuser,$udom,$uname,$what)
        &Debug("cmd = ".$cmd." exedom= ".$exedom.   =split(/:/,$userinput);
     "user = ".$exeuser." udom=".$udom.      &Debug("cmd = ".$cmd." exedom= ".$exedom.
     "what = ".$what);     "user = ".$exeuser." udom=".$udom.
                        my $namespace='roles';     "what = ".$what);
                        chomp($what);      my $namespace='roles';
                        my $proname=propath($udom,$uname);      chomp($what);
                        my $now=time;      my $proname=propath($udom,$uname);
                        {      my $now=time;
    my $hfh;      {
    if (   my $hfh;
                              $hfh=IO::File->new(">>$proname/$namespace.hist")   if (
        ) {       $hfh=IO::File->new(">>$proname/$namespace.hist")
                                   print $hfh "D:$now:$exedom:$exeuser:$what\n";      ) { 
                                  }      print $hfh "D:$now:$exedom:$exeuser:$what\n";
        }   }
                        my @rolekeys=split(/\&/,$what);      }
        my %hash;      my @rolekeys=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {      my %hash;
                            foreach my $key (@rolekeys) {      if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                                delete $hash{$key};   foreach my $key (@rolekeys) {
                            }      delete $hash{$key};
    if (untie(%hash)) {   }
                               print $client "ok\n";   if (untie(%hash)) {
                            } else {      print $client "ok\n";
                               print $client "error: ".($!+0)   } else {
   ." untie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting rolesdel\n";   ." untie(GDBM) Failed ".
                            }   "while attempting rolesdel\n";
                        } else {   }
                            print $client "error: ".($!+0)      } else {
        ." tie(GDBM) Failed ".   print $client "error: ".($!+0)
                                    "while attempting rolesdel\n";      ." tie(GDBM) Failed ".
                        }      "while attempting rolesdel\n";
       } else {      }
                           print $client "refused\n";   } else {
                       }      print $client "refused\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
         
       }
 # ------------------------------------------------------------------------- get  # ------------------------------------------------------------------------- get
                    } elsif ($userinput =~ /^get/) {   } elsif ($userinput =~ /^get/) {
                        my ($cmd,$udom,$uname,$namespace,$what)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$what)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        chomp($what);   $namespace=~s/\W//g;
                        my @queries=split(/\&/,$what);   chomp($what);
                        my $proname=propath($udom,$uname);   my @queries=split(/\&/,$what);
                        my $qresult='';   my $proname=propath($udom,$uname);
        my %hash;   my $qresult='';
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {   my %hash;
                            for (my $i=0;$i<=$#queries;$i++) {   if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                                $qresult.="$hash{$queries[$i]}&";      for (my $i=0;$i<=$#queries;$i++) {
                            }   $qresult.="$hash{$queries[$i]}&";
    if (untie(%hash)) {      }
               $qresult=~s/\&$//;      if (untie(%hash)) {
                               print $client "$qresult\n";   $qresult=~s/\&$//;
                            } else {   print $client "$qresult\n";
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting get\n";      ." untie(GDBM) Failed ".
                            }      "while attempting get\n";
                        } else {      }
                            if ($!+0 == 2) {   } else {
                                print $client "error:No such file or ".      if ($!+0 == 2) {
                                    "GDBM reported bad block error\n";   print $client "error:No such file or ".
                            } else {      "GDBM reported bad block error\n";
                                print $client "error: ".($!+0)      } else {
                                    ." tie(GDBM) Failed ".   print $client "error: ".($!+0)
                                        "while attempting get\n";      ." tie(GDBM) Failed ".
                            }      "while attempting get\n";
                        }      }
    }
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ------------------------------------------------------------------------ eget  # ------------------------------------------------------------------------ eget
                    } elsif ($userinput =~ /^eget/) {   } elsif ($userinput =~ /^eget/) {
                        my ($cmd,$udom,$uname,$namespace,$what)      if (isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$what)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        chomp($what);   $namespace=~s/\W//g;
                        my @queries=split(/\&/,$what);   chomp($what);
                        my $proname=propath($udom,$uname);   my @queries=split(/\&/,$what);
                        my $qresult='';   my $proname=propath($udom,$uname);
        my %hash;   my $qresult='';
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {   my %hash;
                            for (my $i=0;$i<=$#queries;$i++) {   if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                                $qresult.="$hash{$queries[$i]}&";      for (my $i=0;$i<=$#queries;$i++) {
                            }   $qresult.="$hash{$queries[$i]}&";
    if (untie(%hash)) {      }
               $qresult=~s/\&$//;      if (untie(%hash)) {
                               if ($cipher) {   $qresult=~s/\&$//;
                                 my $cmdlength=length($qresult);   if ($cipher) {
                                 $qresult.="         ";      my $cmdlength=length($qresult);
                                 my $encqresult='';      $qresult.="         ";
                                 for       my $encqresult='';
  (my $encidx=0;$encidx<=$cmdlength;$encidx+=8) {      for 
                                  $encqresult.=   (my $encidx=0;$encidx<=$cmdlength;$encidx+=8) {
                                  unpack("H16",      $encqresult.=
                                  $cipher->encrypt(substr($qresult,$encidx,8)));   unpack("H16",
                                 }         $cipher->encrypt(substr($qresult,$encidx,8)));
                                 print $client "enc:$cmdlength:$encqresult\n";   }
       } else {      print $client "enc:$cmdlength:$encqresult\n";
         print $client "error:no_key\n";   } else {
                               }      print $client "error:no_key\n";
                            } else {   }
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting eget\n";      ." untie(GDBM) Failed ".
                            }      "while attempting eget\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                    "while attempting eget\n";   ." tie(GDBM) Failed ".
                        }   "while attempting eget\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
       
       }
 # ------------------------------------------------------------------------- del  # ------------------------------------------------------------------------- del
                    } elsif ($userinput =~ /^del/) {   } elsif ($userinput =~ /^del/) {
                        my ($cmd,$udom,$uname,$namespace,$what)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$what)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        chomp($what);   $namespace=~s/\W//g;
                        my $proname=propath($udom,$uname);   chomp($what);
                        my $now=time;   my $proname=propath($udom,$uname);
                        unless ($namespace=~/^nohist\_/) {   my $now=time;
    my $hfh;   unless ($namespace=~/^nohist\_/) {
    if (      my $hfh;
                              $hfh=IO::File->new(">>$proname/$namespace.hist")      if (
        ) { print $hfh "D:$now:$what\n"; }   $hfh=IO::File->new(">>$proname/$namespace.hist")
        }   ) { print $hfh "D:$now:$what\n"; }
                        my @keys=split(/\&/,$what);   }
        my %hash;   my @keys=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {   my %hash;
                            foreach my $key (@keys) {   if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                                delete($hash{$key});      foreach my $key (@keys) {
                            }   delete($hash{$key});
    if (untie(%hash)) {      }
                               print $client "ok\n";      if (untie(%hash)) {
                            } else {   print $client "ok\n";
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting del\n";      ." untie(GDBM) Failed ".
                            }      "while attempting del\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                    "while attempting del\n";   ." tie(GDBM) Failed ".
                        }   "while attempting del\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
   
       }
 # ------------------------------------------------------------------------ keys  # ------------------------------------------------------------------------ keys
                    } elsif ($userinput =~ /^keys/) {   } elsif ($userinput =~ /^keys/) {
                        my ($cmd,$udom,$uname,$namespace)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        my $proname=propath($udom,$uname);   $namespace=~s/\W//g;
                        my $qresult='';   my $proname=propath($udom,$uname);
        my %hash;   my $qresult='';
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {   my %hash;
                            foreach my $key (keys %hash) {   if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                                $qresult.="$key&";      foreach my $key (keys %hash) {
                            }   $qresult.="$key&";
    if (untie(%hash)) {      }
               $qresult=~s/\&$//;      if (untie(%hash)) {
                               print $client "$qresult\n";   $qresult=~s/\&$//;
                            } else {   print $client "$qresult\n";
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting keys\n";      ." untie(GDBM) Failed ".
                            }      "while attempting keys\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                    "while attempting keys\n";   ." tie(GDBM) Failed ".
                        }   "while attempting keys\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
      
       }
 # ----------------------------------------------------------------- dumpcurrent  # ----------------------------------------------------------------- dumpcurrent
                    } elsif ($userinput =~ /^currentdump/) {   } elsif ($userinput =~ /^currentdump/) {
                        my ($cmd,$udom,$uname,$namespace)      if (isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        my $qresult='';   $namespace=~s/\W//g;
                        my $proname=propath($udom,$uname);   my $qresult='';
        my %hash;   my $proname=propath($udom,$uname);
                        if (tie(%hash,'GDBM_File',   my %hash;
                                "$proname/$namespace.db",   if (tie(%hash,'GDBM_File',
                                &GDBM_READER(),0640)) {   "$proname/$namespace.db",
                            # Structure of %data:   &GDBM_READER(),0640)) {
                            # $data{$symb}->{$parameter}=$value;      # Structure of %data:
                            # $data{$symb}->{'v.'.$parameter}=$version;      # $data{$symb}->{$parameter}=$value;
                            # since $parameter will be unescaped, we do not      # $data{$symb}->{'v.'.$parameter}=$version;
                            # have to worry about silly parameter names...      # since $parameter will be unescaped, we do not
                            my %data = ();      # have to worry about silly parameter names...
                            while (my ($key,$value) = each(%hash)) {      my %data = ();
                               my ($v,$symb,$param) = split(/:/,$key);      while (my ($key,$value) = each(%hash)) {
                               next if ($v eq 'version' || $symb eq 'keys');   my ($v,$symb,$param) = split(/:/,$key);
                               next if (exists($data{$symb}) &&    next if ($v eq 'version' || $symb eq 'keys');
                                        exists($data{$symb}->{$param}) &&   next if (exists($data{$symb}) && 
                                        $data{$symb}->{'v.'.$param} > $v);   exists($data{$symb}->{$param}) &&
                               $data{$symb}->{$param}=$value;   $data{$symb}->{'v.'.$param} > $v);
                               $data{$symb}->{'v.'.$param}=$v;   $data{$symb}->{$param}=$value;
                            }   $data{$symb}->{'v.'.$param}=$v;
                            if (untie(%hash)) {      }
                              while (my ($symb,$param_hash) = each(%data)) {      if (untie(%hash)) {
                                while(my ($param,$value) = each (%$param_hash)){   while (my ($symb,$param_hash) = each(%data)) {
                                  next if ($param =~ /^v\./);      while(my ($param,$value) = each (%$param_hash)){
                                  $qresult.=$symb.':'.$param.'='.$value.'&';   next if ($param =~ /^v\./);
                                }   $qresult.=$symb.':'.$param.'='.$value.'&';
                              }      }
                              chop($qresult);   }
                              print $client "$qresult\n";   chop($qresult);
                            } else {   print $client "$qresult\n";
                              print $client "error: ".($!+0)      } else {
  ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                      "while attempting currentdump\n";      ." untie(GDBM) Failed ".
                            }      "while attempting currentdump\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting currentdump\n";   ." tie(GDBM) Failed ".
                        }   "while attempting currentdump\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
       }
 # ------------------------------------------------------------------------ dump  # ------------------------------------------------------------------------ dump
                    } elsif ($userinput =~ /^dump/) {   } elsif ($userinput =~ /^dump/) {
                        my ($cmd,$udom,$uname,$namespace,$regexp)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$regexp)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        if (defined($regexp)) {   $namespace=~s/\W//g;
                           $regexp=&unescape($regexp);   if (defined($regexp)) {
        } else {      $regexp=&unescape($regexp);
                           $regexp='.';   } else {
        }      $regexp='.';
                        my $qresult='';   }
                        my $proname=propath($udom,$uname);   my $qresult='';
        my %hash;   my $proname=propath($udom,$uname);
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {   my %hash;
                            study($regexp);   if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                            while (my ($key,$value) = each(%hash)) {         study($regexp);
                                if ($regexp eq '.') {         while (my ($key,$value) = each(%hash)) {
                                    $qresult.=$key.'='.$value.'&';     if ($regexp eq '.') {
                                } else {         $qresult.=$key.'='.$value.'&';
                                    my $unescapeKey = &unescape($key);     } else {
                                    if (eval('$unescapeKey=~/$regexp/')) {         my $unescapeKey = &unescape($key);
                                        $qresult.="$key=$value&";         if (eval('$unescapeKey=~/$regexp/')) {
                                    }     $qresult.="$key=$value&";
                                }         }
                            }     }
                            if (untie(%hash)) {         }
                                chop($qresult);         if (untie(%hash)) {
                                print $client "$qresult\n";     chop($qresult);
                            } else {     print $client "$qresult\n";
                                print $client "error: ".($!+0)         } else {
    ." untie(GDBM) Failed ".     print $client "error: ".($!+0)
          ." untie(GDBM) Failed ".
                                        "while attempting dump\n";                                         "while attempting dump\n";
                            }         }
                        } else {     } else {
                            print $client "error: ".($!+0)         print $client "error: ".($!+0)
        ." tie(GDBM) Failed ".     ." tie(GDBM) Failed ".
                                       "while attempting dump\n";     "while attempting dump\n";
                        }     }
       } else {
    Reply($client, "refused\n", $userinput);
     
       }
 # ----------------------------------------------------------------------- store  # ----------------------------------------------------------------------- store
                    } elsif ($userinput =~ /^store/) {   } elsif ($userinput =~ /^store/) {
                       my ($cmd,$udom,$uname,$namespace,$rid,$what)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$rid,$what)
                       $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                       $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                       if ($namespace ne 'roles') {   $namespace=~s/\W//g;
                        chomp($what);   if ($namespace ne 'roles') {
                        my $proname=propath($udom,$uname);      chomp($what);
                        my $now=time;      my $proname=propath($udom,$uname);
                        unless ($namespace=~/^nohist\_/) {      my $now=time;
    my $hfh;      unless ($namespace=~/^nohist\_/) {
    if (   my $hfh;
                              $hfh=IO::File->new(">>$proname/$namespace.hist")   if (
        ) { print $hfh "P:$now:$rid:$what\n"; }      $hfh=IO::File->new(">>$proname/$namespace.hist")
        }      ) { print $hfh "P:$now:$rid:$what\n"; }
                        my @pairs=split(/\&/,$what);      }
        my %hash;      my @pairs=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {      my %hash;
                            my @previouskeys=split(/&/,$hash{"keys:$rid"});      if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                            my $key;   my @previouskeys=split(/&/,$hash{"keys:$rid"});
                            $hash{"version:$rid"}++;   my $key;
                            my $version=$hash{"version:$rid"};   $hash{"version:$rid"}++;
                            my $allkeys='';    my $version=$hash{"version:$rid"};
                            foreach my $pair (@pairs) {   my $allkeys=''; 
        my ($key,$value)=split(/=/,$pair);   foreach my $pair (@pairs) {
                                $allkeys.=$key.':';      my ($key,$value)=split(/=/,$pair);
                                $hash{"$version:$rid:$key"}=$value;      $allkeys.=$key.':';
                            }      $hash{"$version:$rid:$key"}=$value;
                            $hash{"$version:$rid:timestamp"}=$now;   }
                            $allkeys.='timestamp';   $hash{"$version:$rid:timestamp"}=$now;
                            $hash{"$version:keys:$rid"}=$allkeys;   $allkeys.='timestamp';
    if (untie(%hash)) {   $hash{"$version:keys:$rid"}=$allkeys;
                               print $client "ok\n";   if (untie(%hash)) {
                            } else {      print $client "ok\n";
                               print $client "error: ".($!+0)   } else {
   ." untie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting store\n";   ." untie(GDBM) Failed ".
                            }   "while attempting store\n";
                        } else {   }
                            print $client "error: ".($!+0)      } else {
        ." tie(GDBM) Failed ".   print $client "error: ".($!+0)
                                    "while attempting store\n";      ." tie(GDBM) Failed ".
                        }      "while attempting store\n";
       } else {      }
                           print $client "refused\n";   } else {
                       }      print $client "refused\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
        
       }
 # --------------------------------------------------------------------- restore  # --------------------------------------------------------------------- restore
                    } elsif ($userinput =~ /^restore/) {   } elsif ($userinput =~ /^restore/) {
                        my ($cmd,$udom,$uname,$namespace,$rid)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$uname,$namespace,$rid)
                        $namespace=~s/\//\_/g;      =split(/:/,$userinput);
                        $namespace=~s/\W//g;   $namespace=~s/\//\_/g;
                        chomp($rid);   $namespace=~s/\W//g;
                        my $proname=propath($udom,$uname);   chomp($rid);
                        my $qresult='';   my $proname=propath($udom,$uname);
        my %hash;   my $qresult='';
        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {   my %hash;
                   my $version=$hash{"version:$rid"};   if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                            $qresult.="version=$version&";      my $version=$hash{"version:$rid"};
                            my $scope;      $qresult.="version=$version&";
                            for ($scope=1;$scope<=$version;$scope++) {      my $scope;
       my $vkeys=$hash{"$scope:keys:$rid"};      for ($scope=1;$scope<=$version;$scope++) {
                               my @keys=split(/:/,$vkeys);   my $vkeys=$hash{"$scope:keys:$rid"};
                               my $key;   my @keys=split(/:/,$vkeys);
                               $qresult.="$scope:keys=$vkeys&";   my $key;
                               foreach $key (@keys) {   $qresult.="$scope:keys=$vkeys&";
      $qresult.="$scope:$key=".$hash{"$scope:$rid:$key"}."&";   foreach $key (@keys) {
                               }                                        $qresult.="$scope:$key=".$hash{"$scope:$rid:$key"}."&";
                            }   }                                  
    if (untie(%hash)) {      }
               $qresult=~s/\&$//;      if (untie(%hash)) {
                               print $client "$qresult\n";   $qresult=~s/\&$//;
                            } else {   print $client "$qresult\n";
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting restore\n";      ." untie(GDBM) Failed ".
                            }      "while attempting restore\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                    "while attempting restore\n";   ." tie(GDBM) Failed ".
                        }   "while attempting restore\n";
    }
       } else  {
    Reply($client, "refused\n", $userinput);
          
       }
 # -------------------------------------------------------------------- chatsend  # -------------------------------------------------------------------- chatsend
                    } elsif ($userinput =~ /^chatsend/) {   } elsif ($userinput =~ /^chatsend/) {
                        my ($cmd,$cdom,$cnum,$newpost)=split(/\:/,$userinput);      if(isClient) {
                        &chatadd($cdom,$cnum,$newpost);   my ($cmd,$cdom,$cnum,$newpost)=split(/\:/,$userinput);
                        print $client "ok\n";   &chatadd($cdom,$cnum,$newpost);
    print $client "ok\n";
       } else {
    Reply($client, "refused\n", $userinput);
         
       }
 # -------------------------------------------------------------------- chatretr  # -------------------------------------------------------------------- chatretr
                    } elsif ($userinput =~ /^chatretr/) {   } elsif ($userinput =~ /^chatretr/) {
                        my       if(isClient) {
                         ($cmd,$cdom,$cnum,$udom,$uname)=split(/\:/,$userinput);   my 
                        my $reply='';      ($cmd,$cdom,$cnum,$udom,$uname)=split(/\:/,$userinput);
                        foreach (&getchat($cdom,$cnum,$udom,$uname)) {   my $reply='';
    $reply.=&escape($_).':';   foreach (&getchat($cdom,$cnum,$udom,$uname)) {
                        }      $reply.=&escape($_).':';
                        $reply=~s/\:$//;   }
                        print $client $reply."\n";   $reply=~s/\:$//;
    print $client $reply."\n";
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ------------------------------------------------------------------- querysend  # ------------------------------------------------------------------- querysend
                    } elsif ($userinput =~ /^querysend/) {   } elsif ($userinput =~ /^querysend/) {
                        my ($cmd,$query,      if(isClient) {
    $arg1,$arg2,$arg3)=split(/\:/,$userinput);   my ($cmd,$query,
        $query=~s/\n*$//g;      $arg1,$arg2,$arg3)=split(/\:/,$userinput);
        print $client "".   $query=~s/\n*$//g;
        sqlreply("$hostid{$clientip}\&$query".   print $client "".
  "\&$arg1"."\&$arg2"."\&$arg3")."\n";      sqlreply("$clientname\&$query".
        "\&$arg1"."\&$arg2"."\&$arg3")."\n";
       } else {
    Reply($client, "refused\n", $userinput);
         
       }
 # ------------------------------------------------------------------ queryreply  # ------------------------------------------------------------------ queryreply
                    } elsif ($userinput =~ /^queryreply/) {   } elsif ($userinput =~ /^queryreply/) {
                        my ($cmd,$id,$reply)=split(/:/,$userinput);       if(isClient) {
        my $store;   my ($cmd,$id,$reply)=split(/:/,$userinput); 
                        my $execdir=$perlvar{'lonDaemons'};   my $store;
                        if ($store=IO::File->new(">$execdir/tmp/$id")) {   my $execdir=$perlvar{'lonDaemons'};
    $reply=~s/\&/\n/g;   if ($store=IO::File->new(">$execdir/tmp/$id")) {
    print $store $reply;      $reply=~s/\&/\n/g;
    close $store;      print $store $reply;
    my $store2=IO::File->new(">$execdir/tmp/$id.end");      close $store;
    print $store2 "done\n";      my $store2=IO::File->new(">$execdir/tmp/$id.end");
    close $store2;      print $store2 "done\n";
    print $client "ok\n";      close $store2;
        }      print $client "ok\n";
        else {   }
    print $client "error: ".($!+0)   else {
        ." IO::File->new Failed ".      print $client "error: ".($!+0)
                                    "while attempting queryreply\n";   ." IO::File->new Failed ".
        }   "while attempting queryreply\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
        
       }
 # ----------------------------------------------------------------- courseidput  # ----------------------------------------------------------------- courseidput
                    } elsif ($userinput =~ /^courseidput/) {   } elsif ($userinput =~ /^courseidput/) {
                        my ($cmd,$udom,$what)=split(/:/,$userinput);      if(isClient) {
                        chomp($what);   my ($cmd,$udom,$what)=split(/:/,$userinput);
                        $udom=~s/\W//g;   chomp($what);
                        my $proname=   $udom=~s/\W//g;
                               "$perlvar{'lonUsersDir'}/$udom/nohist_courseids";   my $proname=
                        my $now=time;      "$perlvar{'lonUsersDir'}/$udom/nohist_courseids";
                        my @pairs=split(/\&/,$what);   my $now=time;
        my %hash;   my @pairs=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) {   my %hash;
                            foreach my $pair (@pairs) {   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) {
        my ($key,$value)=split(/=/,$pair);      foreach my $pair (@pairs) {
                                $hash{$key}=$value.':'.$now;   my ($key,$value)=split(/=/,$pair);
                            }   $hash{$key}=$value.':'.$now;
    if (untie(%hash)) {      }
                               print $client "ok\n";      if (untie(%hash)) {
                            } else {   print $client "ok\n";
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting courseidput\n";      ." untie(GDBM) Failed ".
                            }      "while attempting courseidput\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting courseidput\n";   ." tie(GDBM) Failed ".
                        }   "while attempting courseidput\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ---------------------------------------------------------------- courseiddump  # ---------------------------------------------------------------- courseiddump
                    } elsif ($userinput =~ /^courseiddump/) {   } elsif ($userinput =~ /^courseiddump/) {
                        my ($cmd,$udom,$since,$description)      if(isClient) {
                           =split(/:/,$userinput);   my ($cmd,$udom,$since,$description)
                        if (defined($description)) {      =split(/:/,$userinput);
                           $description=&unescape($description);   if (defined($description)) {
        } else {      $description=&unescape($description);
                           $description='.';   } else {
        }      $description='.';
                        unless (defined($since)) { $since=0; }   }
                        my $qresult='';   unless (defined($since)) { $since=0; }
                        my $proname=   my $qresult='';
                               "$perlvar{'lonUsersDir'}/$udom/nohist_courseids";   my $proname=
        my %hash;      "$perlvar{'lonUsersDir'}/$udom/nohist_courseids";
        if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) {   my %hash;
                            while (my ($key,$value) = each(%hash)) {   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) {
                                my ($descr,$lasttime)=split(/\:/,$value);      while (my ($key,$value) = each(%hash)) {
                                if ($lasttime<$since) { next; }   my ($descr,$lasttime)=split(/\:/,$value);
                                if ($description eq '.') {   if ($lasttime<$since) { next; }
                                    $qresult.=$key.'='.$descr.'&';   if ($description eq '.') {
                                } else {      $qresult.=$key.'='.$descr.'&';
                                    my $unescapeVal = &unescape($descr);   } else {
                                    if (eval('$unescapeVal=~/$description/i')) {      my $unescapeVal = &unescape($descr);
                                        $qresult.="$key=$descr&";      if (eval('$unescapeVal=~/$description/i')) {
                                    }   $qresult.="$key=$descr&";
                                }      }
                            }   }
                            if (untie(%hash)) {      }
                                chop($qresult);      if (untie(%hash)) {
                                print $client "$qresult\n";   chop($qresult);
                            } else {   print $client "$qresult\n";
                                print $client "error: ".($!+0)      } else {
    ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                        "while attempting courseiddump\n";      ." untie(GDBM) Failed ".
                            }      "while attempting courseiddump\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting courseiddump\n";   ." tie(GDBM) Failed ".
                        }   "while attempting courseiddump\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ----------------------------------------------------------------------- idput  # ----------------------------------------------------------------------- idput
                    } elsif ($userinput =~ /^idput/) {   } elsif ($userinput =~ /^idput/) {
                        my ($cmd,$udom,$what)=split(/:/,$userinput);      if(isClient) {
                        chomp($what);   my ($cmd,$udom,$what)=split(/:/,$userinput);
                        $udom=~s/\W//g;   chomp($what);
                        my $proname="$perlvar{'lonUsersDir'}/$udom/ids";   $udom=~s/\W//g;
                        my $now=time;   my $proname="$perlvar{'lonUsersDir'}/$udom/ids";
                        {   my $now=time;
    my $hfh;   {
    if (      my $hfh;
                              $hfh=IO::File->new(">>$proname.hist")      if (
        ) { print $hfh "P:$now:$what\n"; }   $hfh=IO::File->new(">>$proname.hist")
        }   ) { print $hfh "P:$now:$what\n"; }
                        my @pairs=split(/\&/,$what);   }
        my %hash;   my @pairs=split(/\&/,$what);
        if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) {   my %hash;
                            foreach my $pair (@pairs) {   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) {
        my ($key,$value)=split(/=/,$pair);      foreach my $pair (@pairs) {
                                $hash{$key}=$value;   my ($key,$value)=split(/=/,$pair);
                            }   $hash{$key}=$value;
    if (untie(%hash)) {      }
                               print $client "ok\n";      if (untie(%hash)) {
                            } else {   print $client "ok\n";
                               print $client "error: ".($!+0)      } else {
   ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
                                       "while attempting idput\n";      ." untie(GDBM) Failed ".
                            }      "while attempting idput\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                       "while attempting idput\n";   ." tie(GDBM) Failed ".
                        }   "while attempting idput\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ----------------------------------------------------------------------- idget  # ----------------------------------------------------------------------- idget
                    } elsif ($userinput =~ /^idget/) {   } elsif ($userinput =~ /^idget/) {
                        my ($cmd,$udom,$what)=split(/:/,$userinput);      if(isClient) {
                        chomp($what);   my ($cmd,$udom,$what)=split(/:/,$userinput);
                        $udom=~s/\W//g;   chomp($what);
                        my $proname="$perlvar{'lonUsersDir'}/$udom/ids";   $udom=~s/\W//g;
                        my @queries=split(/\&/,$what);   my $proname="$perlvar{'lonUsersDir'}/$udom/ids";
                        my $qresult='';   my @queries=split(/\&/,$what);
        my %hash;   my $qresult='';
        if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) {   my %hash;
                            for (my $i=0;$i<=$#queries;$i++) {   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) {
                                $qresult.="$hash{$queries[$i]}&";      for (my $i=0;$i<=$#queries;$i++) {
                            }   $qresult.="$hash{$queries[$i]}&";
    if (untie(%hash)) {      }
        $qresult=~s/\&$//;      if (untie(%hash)) {
        print $client "$qresult\n";   $qresult=~s/\&$//;
                            } else {   print $client "$qresult\n";
        print $client "error: ".($!+0)      } else {
    ." untie(GDBM) Failed ".   print $client "error: ".($!+0)
        "while attempting idget\n";      ." untie(GDBM) Failed ".
                            }      "while attempting idget\n";
                        } else {      }
                            print $client "error: ".($!+0)   } else {
        ." tie(GDBM) Failed ".      print $client "error: ".($!+0)
                                    "while attempting idget\n";   ." tie(GDBM) Failed ".
                        }   "while attempting idget\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ---------------------------------------------------------------------- tmpput  # ---------------------------------------------------------------------- tmpput
                    } elsif ($userinput =~ /^tmpput/) {   } elsif ($userinput =~ /^tmpput/) {
                        my ($cmd,$what)=split(/:/,$userinput);      if(isClient) {
        my $store;   my ($cmd,$what)=split(/:/,$userinput);
                        $tmpsnum++;   my $store;
                        my $id=$$.'_'.$clientip.'_'.$tmpsnum;   $tmpsnum++;
                        $id=~s/\W/\_/g;   my $id=$$.'_'.$clientip.'_'.$tmpsnum;
                        $what=~s/\n//g;   $id=~s/\W/\_/g;
                        my $execdir=$perlvar{'lonDaemons'};   $what=~s/\n//g;
                        if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) {   my $execdir=$perlvar{'lonDaemons'};
    print $store $what;   if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) {
    close $store;      print $store $what;
    print $client "$id\n";      close $store;
        }      print $client "$id\n";
        else {   }
    print $client "error: ".($!+0)   else {
        ."IO::File->new Failed ".      print $client "error: ".($!+0)
                                    "while attempting tmpput\n";   ."IO::File->new Failed ".
        }   "while attempting tmpput\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
       
       }
       
 # ---------------------------------------------------------------------- tmpget  # ---------------------------------------------------------------------- tmpget
                    } elsif ($userinput =~ /^tmpget/) {   } elsif ($userinput =~ /^tmpget/) {
                        my ($cmd,$id)=split(/:/,$userinput);      if(isClient) {
                        chomp($id);   my ($cmd,$id)=split(/:/,$userinput);
                        $id=~s/\W/\_/g;   chomp($id);
                        my $store;   $id=~s/\W/\_/g;
                        my $execdir=$perlvar{'lonDaemons'};   my $store;
                        if ($store=IO::File->new("$execdir/tmp/$id.tmp")) {   my $execdir=$perlvar{'lonDaemons'};
                            my $reply=<$store>;   if ($store=IO::File->new("$execdir/tmp/$id.tmp")) {
    print $client "$reply\n";      my $reply=<$store>;
                            close $store;      print $client "$reply\n";
        }      close $store;
        else {   }
    print $client "error: ".($!+0)   else {
        ."IO::File->new Failed ".      print $client "error: ".($!+0)
                                    "while attempting tmpget\n";   ."IO::File->new Failed ".
        }   "while attempting tmpget\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
         
       }
 # ---------------------------------------------------------------------- tmpdel  # ---------------------------------------------------------------------- tmpdel
                    } elsif ($userinput =~ /^tmpdel/) {   } elsif ($userinput =~ /^tmpdel/) {
                        my ($cmd,$id)=split(/:/,$userinput);      if(isClient) {
                        chomp($id);   my ($cmd,$id)=split(/:/,$userinput);
                        $id=~s/\W/\_/g;   chomp($id);
                        my $execdir=$perlvar{'lonDaemons'};   $id=~s/\W/\_/g;
                        if (unlink("$execdir/tmp/$id.tmp")) {   my $execdir=$perlvar{'lonDaemons'};
    print $client "ok\n";   if (unlink("$execdir/tmp/$id.tmp")) {
        } else {      print $client "ok\n";
    print $client "error: ".($!+0)   } else {
        ."Unlink tmp Failed ".      print $client "error: ".($!+0)
                                    "while attempting tmpdel\n";   ."Unlink tmp Failed ".
        }   "while attempting tmpdel\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
        
       }
 # -------------------------------------------------------------------------- ls  # -------------------------------------------------------------------------- ls
                    } elsif ($userinput =~ /^ls/) {   } elsif ($userinput =~ /^ls/) {
                        my ($cmd,$ulsdir)=split(/:/,$userinput);      if(isClient) {
                        my $ulsout='';   my ($cmd,$ulsdir)=split(/:/,$userinput);
                        my $ulsfn;   my $ulsout='';
                        if (-e $ulsdir) {   my $ulsfn;
                            if(-d $ulsdir) {   if (-e $ulsdir) {
                                if (opendir(LSDIR,$ulsdir)) {      if(-d $ulsdir) {
                                    while ($ulsfn=readdir(LSDIR)) {   if (opendir(LSDIR,$ulsdir)) {
                                        my @ulsstats=stat($ulsdir.'/'.$ulsfn);      while ($ulsfn=readdir(LSDIR)) {
                                        $ulsout.=$ulsfn.'&'.   my @ulsstats=stat($ulsdir.'/'.$ulsfn);
                                                 join('&',@ulsstats).':';   $ulsout.=$ulsfn.'&'.
                                    }      join('&',@ulsstats).':';
                                    closedir(LSDIR);      }
                                }      closedir(LSDIR);
                            } else {   }
                                my @ulsstats=stat($ulsdir);      } else {
                                $ulsout.=$ulsfn.'&'.join('&',@ulsstats).':';   my @ulsstats=stat($ulsdir);
                            }   $ulsout.=$ulsfn.'&'.join('&',@ulsstats).':';
                        } else {      }
                           $ulsout='no_such_dir';   } else {
                        }      $ulsout='no_such_dir';
                        if ($ulsout eq '') { $ulsout='empty'; }   }
                        print $client "$ulsout\n";   if ($ulsout eq '') { $ulsout='empty'; }
    print $client "$ulsout\n";
       } else {
    Reply($client, "refused\n", $userinput);
        
       }
 # ----------------------------------------------------------------- setannounce  # ----------------------------------------------------------------- setannounce
                    } elsif ($userinput =~ /^setannounce/) {   } elsif ($userinput =~ /^setannounce/) {
        my ($cmd,$announcement)=split(/:/,$userinput);      if (isClient) {
        chomp($announcement);   my ($cmd,$announcement)=split(/:/,$userinput);
        $announcement=&unescape($announcement);   chomp($announcement);
                        if (my $store=IO::File->new('>'.$perlvar{'lonDocRoot'}.   $announcement=&unescape($announcement);
  '/announcement.txt')) {   if (my $store=IO::File->new('>'.$perlvar{'lonDocRoot'}.
    print $store $announcement;      '/announcement.txt')) {
                            close $store;      print $store $announcement;
    print $client "ok\n";      close $store;
        } else {      print $client "ok\n";
    print $client "error: ".($!+0)."\n";   } else {
        }      print $client "error: ".($!+0)."\n";
    }
       } else {
    Reply($client, "refused\n", $userinput);
          
       }
 # ------------------------------------------------------------------ Hanging up  # ------------------------------------------------------------------ Hanging up
                    } elsif (($userinput =~ /^exit/) ||   } elsif (($userinput =~ /^exit/) ||
                             ($userinput =~ /^init/)) {   ($userinput =~ /^init/)) { # no restrictions.
                        &logthis(      &logthis(
       "Client $clientip ($hostid{$clientip}) hanging up: $userinput");       "Client $clientip ($clientname) hanging up: $userinput");
                        print $client "bye\n";      print $client "bye\n";
                        $client->close();      $client->close();
        last;      last;
   
   # ---------------------------------- set current host/domain
    } elsif ($userinput =~ /^sethost:/) {
       if (isClient) {
    print $client &sethost($userinput)."\n";
       } else {
    print $client "refused\n";
       }
   #---------------------------------- request file (?) version.
    } elsif ($userinput =~/^version:/) {
       if (isClient) {
    print $client &version($userinput)."\n";
       } else {
    print $client "refused\n";
       }
 # ------------------------------------------------------------- unknown command  # ------------------------------------------------------------- unknown command
    } elsif ($userinput =~ /^sethost:/) {  
        print $client &sethost($userinput)."\n";   } else {
    } elsif ($userinput =~/^version:/) {      # unknown command
        print $client &version($userinput)."\n";      print $client "unknown_cmd\n";
                    } else {   }
                        # unknown command  
                        print $client "unknown_cmd\n";  
                    }  
 # -------------------------------------------------------------------- complete  # -------------------------------------------------------------------- complete
    alarm(0);   alarm(0);
                    &status('Listening to '.$hostid{$clientip});   &status('Listening to '.$clientname);
        }      }
 # --------------------------------------------- client unknown or fishy, refuse  # --------------------------------------------- client unknown or fishy, refuse
             } else {   } else {
         print $client "refused\n";      print $client "refused\n";
                 $client->close();      $client->close();
                 &logthis("<font color=blue>WARNING: "      &logthis("<font color=blue>WARNING: "
                 ."Rejected client $clientip, closing connection</font>");       ."Rejected client $clientip, closing connection</font>");
             }   }
  }                   }             
       
 # =============================================================================  # =============================================================================
              
  &logthis("<font color=red>CRITICAL: "      &logthis("<font color=red>CRITICAL: "
  ."Disconnect from $clientip ($hostid{$clientip})</font>");           ."Disconnect from $clientip ($clientname)</font>");    
       
       
         # this exit is VERY important, otherwise the child will become      # this exit is VERY important, otherwise the child will become
         # a producer of more and more children, forking yourself into      # a producer of more and more children, forking yourself into
         # process death.      # process death.
         exit;      exit;
           
 }  }
   
Line 2392  sub chatadd { Line 2664  sub chatadd {
 sub unsub {  sub unsub {
     my ($fname,$clientip)=@_;      my ($fname,$clientip)=@_;
     my $result;      my $result;
     if (unlink("$fname.$hostid{$clientip}")) {      if (unlink("$fname.$clientname")) {
  $result="ok\n";   $result="ok\n";
     } else {      } else {
  $result="not_subscribed\n";   $result="not_subscribed\n";
     }      }
     if (-e "$fname.subscription") {      if (-e "$fname.subscription") {
  my $found=&addline($fname,$hostid{$clientip},$clientip,'');   my $found=&addline($fname,$clientname,$clientip,'');
  if ($found) { $result="ok\n"; }   if ($found) { $result="ok\n"; }
     } else {      } else {
  if ($result != "ok\n") { $result="not_subscribed\n"; }   if ($result != "ok\n") { $result="not_subscribed\n"; }
Line 2478  sub subscribe { Line 2750  sub subscribe {
     if (-d $fname) {      if (-d $fname) {
  $result="directory\n";   $result="directory\n";
     } else {      } else {
  if (-e "$fname.$hostid{$clientip}") {&unsub($fname,$clientip);}   if (-e "$fname.$clientname") {&unsub($fname,$clientip);}
  my $now=time;   my $now=time;
  my $found=&addline($fname,$hostid{$clientip},$clientip,   my $found=&addline($fname,$clientname,$clientip,
    "$hostid{$clientip}:$clientip:$now\n");     "$clientname:$clientip:$now\n");
  if ($found) { $result="$fname\n"; }   if ($found) { $result="$fname\n"; }
  # if they were subscribed to only meta data, delete that   # if they were subscribed to only meta data, delete that
                 # subscription, when you subscribe to a file you also get                  # subscription, when you subscribe to a file you also get

Removed from v.1.160  
changed lines
  Added in v.1.161


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>