Diff for /loncom/lond between versions 1.78 and 1.128

version 1.78, 2002/05/03 03:21:25 version 1.128, 2003/05/08 21:35:48
Line 31 Line 31
 # 10/7,10/8,10/9,10/11,10/13,10/15,11/4,11/16,  # 10/7,10/8,10/9,10/11,10/13,10/15,11/4,11/16,
 # 12/7,12/15,01/06,01/11,01/12,01/14,2/8,  # 12/7,12/15,01/06,01/11,01/12,01/14,2/8,
 # 03/07,05/31 Gerd Kortemeyer  # 03/07,05/31 Gerd Kortemeyer
 # 06/26 Scott Harrison  
 # 06/29,06/30,07/14,07/15,07/17,07/20,07/25,09/18 Gerd Kortemeyer  # 06/29,06/30,07/14,07/15,07/17,07/20,07/25,09/18 Gerd Kortemeyer
 # 12/05 Scott Harrison  
 # 12/05,12/13,12/29 Gerd Kortemeyer  # 12/05,12/13,12/29 Gerd Kortemeyer
 # YEAR=2001  # YEAR=2001
 # Jan 01 Scott Harrison  
 # 02/12 Gerd Kortemeyer  # 02/12 Gerd Kortemeyer
 # 03/15 Scott Harrison  
 # 03/24 Gerd Kortemeyer  # 03/24 Gerd Kortemeyer
 # 04/02 Scott Harrison  
 # 05/11,05/28,08/30 Gerd Kortemeyer  # 05/11,05/28,08/30 Gerd Kortemeyer
 # 9/30,10/22,11/13,11/15,11/16 Scott Harrison  
 # 11/26,11/27 Gerd Kortemeyer  # 11/26,11/27 Gerd Kortemeyer
 # 12/20 Scott Harrison  
 # 12/22 Gerd Kortemeyer  # 12/22 Gerd Kortemeyer
 # YEAR=2002  # YEAR=2002
 # 01/20/02,02/05 Gerd Kortemeyer  # 01/20/02,02/05 Gerd Kortemeyer
 # 02/05 Guy Albertelli  # 02/05 Guy Albertelli
 # 02/07 Scott Harrison  
 # 02/12 Gerd Kortemeyer  # 02/12 Gerd Kortemeyer
 # 02/19 Matthew Hall  # 02/19 Matthew Hall
 # 02/25 Gerd Kortemeyer  # 02/25 Gerd Kortemeyer
   # 01/xx/2003 Ron Fox.. Remove preforking.  This makes the general daemon
   #      logic simpler (and there were problems maintaining the preforked
   #      population).  Since the time averaged connection rate is close to zero
   #      because lonc's purpose is to maintain near continuous connnections,
   #      preforking is not really needed.
 ###  ###
   
 # based on "Perl Cookbook" ISBN 1-56592-243-3  use lib '/home/httpd/lib/perl/';
 # preforker - server who forks first  use LONCAPA::Configuration;
 # runs as a daemon  
 # HUPs  
 # uses IDEA encryption  
   
 use IO::Socket;  use IO::Socket;
 use IO::File;  use IO::File;
 use Apache::File;  #use Apache::File;
 use Symbol;  use Symbol;
 use POSIX;  use POSIX;
 use Crypt::IDEA;  use Crypt::IDEA;
 use LWP::UserAgent();  use LWP::UserAgent();
 use GDBM_File;  use GDBM_File;
 use Authen::Krb4;  use Authen::Krb4;
   use Authen::Krb5;
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use localauth;  use localauth;
   
Line 78  my $DEBUG = 0;         # Non zero to ena Line 73  my $DEBUG = 0;         # Non zero to ena
 my $status='';  my $status='';
 my $lastlog='';  my $lastlog='';
   
   my $VERSION='$Revision$'; #' stupid emacs
   my $remoteVERSION;
   my $currenthostid;
   my $currentdomainid;
   #
   #  The array below are password error strings."
   #
   my $lastpwderror    = 13; # Largest error number from lcpasswd.
   my @passwderrors = ("ok",
      "lcpasswd must be run as user 'www'",
      "lcpasswd got incorrect number of arguments",
      "lcpasswd did not get the right nubmer of input text lines",
      "lcpasswd too many simultaneous pwd changes in progress",
      "lcpasswd User does not exist.",
      "lcpasswd Incorrect current passwd",
      "lcpasswd Unable to su to root.",
      "lcpasswd Cannot set new passwd.",
      "lcpasswd Username has invalid characters",
      "lcpasswd Invalid characters in password",
       "11", "12",
       "lcpasswd Password mismatch");
   
   
   #  The array below are lcuseradd error strings.:
   
   my $lastadderror = 13;
   my @adderrors    = ("ok",
       "User ID mismatch, lcuseradd must run as user www",
       "lcuseradd Incorrect number of command line parameters must be 3",
       "lcuseradd Incorrect number of stdinput lines, must be 3",
       "lcuseradd Too many other simultaneous pwd changes in progress",
       "lcuseradd User does not exist",
       "lcuseradd Unabel to mak ewww member of users's group",
       "lcuseradd Unable to su to root",
       "lcuseradd Unable to set password",
       "lcuseradd Usrname has invbalid charcters",
       "lcuseradd Password has an invalid character",
       "lcuseradd User already exists",
       "lcuseradd Could not add user.",
       "lcuseradd Password mismatch");
   
   
   #
   #  Convert an error return code from lcpasswd to a string value.
   #
   sub lcpasswdstrerror {
       my $ErrorCode = shift;
       if(($ErrorCode < 0) || ($ErrorCode > $lastpwderror)) {
    return "lcpasswd Unrecognized error return value ".$ErrorCode;
       } else {
    return $passwderrors[$ErrorCode];
       }
   }
   
   #
   # Convert an error return code from lcuseradd to a string value:
   #
   sub lcuseraddstrerror {
       my $ErrorCode = shift;
       if(($ErrorCode < 0) || ($ErrorCode > $lastadderror)) {
    return "lcuseradd - Unrecognized error code: ".$ErrorCode;
       } else {
    return $adderrors[$ErrorCode];
       }
   }
   
 # grabs exception and records it to log before exiting  # grabs exception and records it to log before exiting
 sub catchexception {  sub catchexception {
     my ($error)=@_;      my ($error)=@_;
Line 101  sub timeout { Line 162  sub timeout {
 $SIG{'QUIT'}=\&catchexception;  $SIG{'QUIT'}=\&catchexception;
 $SIG{__DIE__}=\&catchexception;  $SIG{__DIE__}=\&catchexception;
   
 # ------------------------------------ Read httpd access.conf and get variables  # ---------------------------------- Read loncapa_apache.conf and loncapa.conf
   &status("Read loncapa.conf and loncapa_apache.conf");
 open (CONFIG,"/etc/httpd/conf/access.conf") || die "Can't read access.conf";  my $perlvarref=LONCAPA::Configuration::read_conf('loncapa.conf');
   my %perlvar=%{$perlvarref};
 while ($configline=<CONFIG>) {  undef $perlvarref;
     if ($configline =~ /PerlSetVar/) {  
  my ($dummy,$varname,$varvalue)=split(/\s+/,$configline);  
         chomp($varvalue);  
         $perlvar{$varname}=$varvalue;  
     }  
 }  
 close(CONFIG);  
   
 # ----------------------------- Make sure this process is running from user=www  # ----------------------------- Make sure this process is running from user=www
 my $wwwid=getpwnam('www');  my $wwwid=getpwnam('www');
 if ($wwwid!=$<) {  if ($wwwid!=$<) {
    $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";     $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
    $subj="LON: $perlvar{'lonHostID'} User ID mismatch";     $subj="LON: $currenthostid User ID mismatch";
    system("echo 'User ID mismatch.  lond must be run as user www.' |\     system("echo 'User ID mismatch.  lond must be run as user www.' |\
  mailto $emailto -s '$subj' > /dev/null");   mailto $emailto -s '$subj' > /dev/null");
    exit 1;     exit 1;
Line 145  while ($configline=<CONFIG>) { Line 199  while ($configline=<CONFIG>) {
     my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);      my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
     chomp($ip); $ip=~s/\D+$//;      chomp($ip); $ip=~s/\D+$//;
     $hostid{$ip}=$id;      $hostid{$ip}=$id;
       $hostdom{$id}=$domain;
       $hostip{$id}=$ip;
     if ($id eq $perlvar{'lonHostID'}) { $thisserver=$name; }      if ($id eq $perlvar{'lonHostID'}) { $thisserver=$name; }
     $PREFORK++;      $PREFORK++;
 }  }
Line 212  sub checkchildren { Line 268  sub checkchildren {
         }           } 
     }      }
     sleep 5;      sleep 5;
       $SIG{ALRM} = sub { die "timeout" };
       $SIG{__DIE__} = 'DEFAULT';
     foreach (sort keys %children) {      foreach (sort keys %children) {
         unless (-e "$docdir/lon-status/londchld/$_.txt") {          unless (-e "$docdir/lon-status/londchld/$_.txt") {
             eval {
               alarm(300);
     &logthis('Child '.$_.' did not respond');      &logthis('Child '.$_.' did not respond');
     kill 9 => $_;      kill 9 => $_;
     $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";      $emailto="$perlvar{'lonAdmEMail'},$perlvar{'lonSysEMail'}";
     $subj="LON: $perlvar{'lonHostID'} killed lond process $_";      $subj="LON: $currenthostid killed lond process $_";
     my $result=`echo 'Killed lond process $_.' | mailto $emailto -s '$subj' > /dev/null`;      my $result=`echo 'Killed lond process $_.' | mailto $emailto -s '$subj' > /dev/null`;
     $execdir=$perlvar{'lonDaemons'};      $execdir=$perlvar{'lonDaemons'};
     $result=`/bin/cp $execdir/logs/lond.log $execdir/logs/lond.log.$_`      $result=`/bin/cp $execdir/logs/lond.log $execdir/logs/lond.log.$_`;
       alarm(0);
     }
         }          }
     }      }
       $SIG{ALRM} = 'DEFAULT';
       $SIG{__DIE__} = \&cathcexception;
 }  }
   
 # --------------------------------------------------------------------- Logging  # --------------------------------------------------------------------- Logging
Line 250  sub logstatus { Line 314  sub logstatus {
     my $docdir=$perlvar{'lonDocRoot'};      my $docdir=$perlvar{'lonDocRoot'};
     {      {
     my $fh=IO::File->new(">>$docdir/lon-status/londstatus.txt");      my $fh=IO::File->new(">>$docdir/lon-status/londstatus.txt");
     print $fh $$."\t".$status."\t".$lastlog."\n";      print $fh $$."\t".$currenthostid."\t".$status."\t".$lastlog."\n";
     $fh->close();      $fh->close();
     }      }
     {      {
Line 280  sub status { Line 344  sub status {
     my $now=time;      my $now=time;
     my $local=localtime($now);      my $local=localtime($now);
     $status=$local.': '.$what;      $status=$local.': '.$what;
       $0='lond: '.$what.' '.$local;
 }  }
   
 # -------------------------------------------------------- Escape Special Chars  # -------------------------------------------------------- Escape Special Chars
Line 310  sub reconlonc { Line 375  sub reconlonc {
         if (kill 0 => $loncpid) {          if (kill 0 => $loncpid) {
     &logthis("lonc at pid $loncpid responding, sending USR1");      &logthis("lonc at pid $loncpid responding, sending USR1");
             kill USR1 => $loncpid;              kill USR1 => $loncpid;
             sleep 5;  
             if (-e "$peerfile") { return; }  
             &logthis("$peerfile still not there, give it another try");  
             sleep 10;  
             if (-e "$peerfile") { return; }  
             &logthis(  
  "<font color=blue>WARNING: $peerfile still not there, giving up</font>");  
         } else {          } else {
     &logthis(      &logthis(
               "<font color=red>CRITICAL: "                "<font color=red>CRITICAL: "
Line 346  sub subreply { Line 404  sub subreply {
 sub reply {  sub reply {
   my ($cmd,$server)=@_;    my ($cmd,$server)=@_;
   my $answer;    my $answer;
   if ($server ne $perlvar{'lonHostID'}) {     if ($server ne $currenthostid) { 
     $answer=subreply($cmd,$server);      $answer=subreply($cmd,$server);
     if ($answer eq 'con_lost') {      if ($answer eq 'con_lost') {
  $answer=subreply("ping",$server);   $answer=subreply("ping",$server);
         if ($answer ne $server) {          if ($answer ne $server) {
     &logthis("sub reply: answer != server");      &logthis("sub reply: answer != server answer is $answer, server is $server");
            &reconlonc("$perlvar{'lonSockDir'}/$server");             &reconlonc("$perlvar{'lonSockDir'}/$server");
         }          }
         $answer=subreply($cmd,$server);          $answer=subreply($cmd,$server);
Line 430  close(PIDSAVE); Line 488  close(PIDSAVE);
 &logthis("<font color=red>CRITICAL: ---------- Starting ----------</font>");  &logthis("<font color=red>CRITICAL: ---------- Starting ----------</font>");
 &status('Starting');  &status('Starting');
   
 # ------------------------------------------------------- Now we are on our own  
       
 # Fork off our children.  
 for (1 .. $PREFORK) {  
     make_new_child();  
 }  
   
 # ----------------------------------------------------- Install signal handlers  # ----------------------------------------------------- Install signal handlers
   
 &status('Forked children');  
   
 $SIG{CHLD} = \&REAPER;  $SIG{CHLD} = \&REAPER;
 $SIG{INT}  = $SIG{TERM} = \&HUNTSMAN;  $SIG{INT}  = $SIG{TERM} = \&HUNTSMAN;
 $SIG{HUP}  = \&HUPSMAN;  $SIG{HUP}  = \&HUPSMAN;
 $SIG{USR1} = \&checkchildren;  $SIG{USR1} = \&checkchildren;
   
 # And maintain the population.  
   
   # --------------------------------------------------------------
   #   Accept connections.  When a connection comes in, it is validated
   #   and if good, a child process is created to process transactions
   #   along the connection.
   
 while (1) {  while (1) {
     &status('Sleeping');      $client = $server->accept() or next;
     sleep;                          # wait for a signal (i.e., child's death)      make_new_child($client);
     &logthis('Woke up');  
     &status('Woke up');  
     for ($i = $children; $i < $PREFORK; $i++) {  
         make_new_child();           # top up the child pool  
     }  
 }  }
   
 sub make_new_child {  sub make_new_child {
       my $client;
     my $pid;      my $pid;
     my $cipher;      my $cipher;
     my $sigset;      my $sigset;
   
       $client = shift;
     &logthis("Attempting to start child");          &logthis("Attempting to start child");    
     # block signal for fork      # block signal for fork
     $sigset = POSIX::SigSet->new(SIGINT);      $sigset = POSIX::SigSet->new(SIGINT);
Line 480  sub make_new_child { Line 536  sub make_new_child {
     } else {      } else {
         # Child can *not* return from this subroutine.          # Child can *not* return from this subroutine.
         $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before          $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before
           $SIG{CHLD} = 'DEFAULT'; #make this default so that pwauth returns 
                                   #don't get intercepted
         $SIG{USR1}= \&logstatus;          $SIG{USR1}= \&logstatus;
         $SIG{ALRM}= \&timeout;          $SIG{ALRM}= \&timeout;
         $lastlog='Forked ';          $lastlog='Forked ';
Line 490  sub make_new_child { Line 548  sub make_new_child {
             or die "Can't unblock SIGINT for fork: $!\n";              or die "Can't unblock SIGINT for fork: $!\n";
   
         $tmpsnum=0;          $tmpsnum=0;
       #---------------------------------------------------- kerberos 5 initialization
         # handle connections until we've reached $MAX_CLIENTS_PER_CHILD          &Authen::Krb5::init_context();
         for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {          &Authen::Krb5::init_ets();
             &status('Idle, waiting for connection');  
             $client = $server->accept()     or last;  
             &status('Accepted connection');              &status('Accepted connection');
 # =============================================================================  # =============================================================================
             # do something with the connection              # do something with the connection
 # -----------------------------------------------------------------------------  # -----------------------------------------------------------------------------
       $client->sockopt(SO_KEEPALIVE, 1);# Enable monitoring of
                                         # connection liveness.
             # 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 $caller=getpeername($client);   my $caller = getpeername($client);
             my ($port,$iaddr)=unpack_sockaddr_in($caller);              my ($port,$iaddr)=unpack_sockaddr_in($caller);
             my $clientip=inet_ntoa($iaddr);              my $clientip=inet_ntoa($iaddr);
             my $clientrec=($hostid{$clientip} ne undef);              my $clientrec=($hostid{$clientip} ne undef);
             &logthis(              &logthis(
 "<font color=yellow>INFO: Connection $i, $clientip ($hostid{$clientip})</font>"  "<font color=yellow>INFO: Connection, $clientip ($hostid{$clientip})</font>"
             );              );
             &status("Connecting $clientip ($hostid{$clientip})");               &status("Connecting $clientip ($hostid{$clientip})"); 
             my $clientok;              my $clientok;
             if ($clientrec) {              if ($clientrec) {
       &status("Waiting for init from $clientip ($hostid{$clientip})");        &status("Waiting for init from $clientip ($hostid{$clientip})");
       my $remotereq=<$client>;        my $remotereq=<$client>;
               $remotereq=~s/\W//g;                $remotereq=~s/[^\w:]//g;
               if ($remotereq eq 'init') {                if ($remotereq =~ /^init/) {
     &sethost("sethost:$perlvar{'lonHostID'}");
   my $challenge="$$".time;    my $challenge="$$".time;
                   print $client "$challenge\n";                    print $client "$challenge\n";
                   &status(                    &status(
Line 542  sub make_new_child { Line 602  sub make_new_child {
             if ($clientok) {              if ($clientok) {
 # ---------------- New known client connecting, could mean machine online again  # ---------------- New known client connecting, could mean machine online again
   
       &reconlonc("$perlvar{'lonSockDir'}/$hostid{$clientip}");   foreach my $id (keys(%hostip)) {
               &logthis(      if ($hostip{$id} ne $clientip ||
        "<font color=green>Established connection: $hostid{$clientip}</font>");         $hostip{$currenthostid} eq $clientip) {
    # no need to try to do recon's to myself
    next;
       }
       &reconlonc("$perlvar{'lonSockDir'}/$id");
    }
    &logthis("<font color=green>Established connection: $hostid{$clientip}</font>");
               &status('Will listen to '.$hostid{$clientip});                &status('Will listen to '.$hostid{$clientip});
 # ------------------------------------------------------------ Process requests  # ------------------------------------------------------------ Process requests
               while (my $userinput=<$client>) {                while (my $userinput=<$client>) {
                 chomp($userinput);                  chomp($userinput);
    Debug("Request = $userinput\n");
                 &status('Processing '.$hostid{$clientip}.': '.$userinput);                  &status('Processing '.$hostid{$clientip}.': '.$userinput);
                 my $wasenc=0;                  my $wasenc=0;
                 alarm(120);                  alarm(120);
Line 571  sub make_new_child { Line 638  sub make_new_child {
 # ------------------------------------------------------------- Normal commands  # ------------------------------------------------------------- Normal commands
 # ------------------------------------------------------------------------ ping  # ------------------------------------------------------------------------ ping
    if ($userinput =~ /^ping/) {     if ($userinput =~ /^ping/) {
                        print $client "$perlvar{'lonHostID'}\n";                         print $client "$currenthostid\n";
 # ------------------------------------------------------------------------ pong  # ------------------------------------------------------------------------ pong
    } elsif ($userinput =~ /^pong/) {     } elsif ($userinput =~ /^pong/) {
                        $reply=reply("ping",$hostid{$clientip});                         $reply=reply("ping",$hostid{$clientip});
                        print $client "$perlvar{'lonHostID'}:$reply\n";                          print $client "$currenthostid:$reply\n"; 
 # ------------------------------------------------------------------------ ekey  # ------------------------------------------------------------------------ ekey
    } elsif ($userinput =~ /^ekey/) {     } elsif ($userinput =~ /^ekey/) {
                        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=$perlvar{'lonHostID'}.$hostid{$clientip};                         my $key=$currenthostid.$hostid{$clientip};
                        $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/;
Line 598  sub make_new_child { Line 665  sub make_new_child {
                           $loadavg=<$loadfile>;                            $loadavg=<$loadfile>;
                        }                         }
                        $loadavg =~ s/\s.*//g;                         $loadavg =~ s/\s.*//g;
                        my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'};         my $loadpercent=100*$loadavg/$perlvar{'lonLoadLim'};
        print $client "$loadpercent\n";         print $client "$loadpercent\n";
   # -------------------------------------------------------------------- userload
      } elsif ($userinput =~ /^userload/) {
          my $userloadpercent=&userload();
          print $client "$userloadpercent\n";
 # ----------------------------------------------------------------- currentauth  # ----------------------------------------------------------------- currentauth
    } elsif ($userinput =~ /^currentauth/) {     } elsif ($userinput =~ /^currentauth/) {
      if ($wasenc==1) {       if ($wasenc==1) {
                        my ($cmd,$udom,$uname)=split(/:/,$userinput);                         my ($cmd,$udom,$uname)=split(/:/,$userinput);
        my $result = GetAuthType($udom, $user);         my $result = GetAuthType($udom, $uname);
        if($result eq "nouser") {         if($result eq "nouser") {
    print $client "unknown_user\n";     print $client "unknown_user\n";
        }         }
Line 629  sub make_new_child { Line 700  sub make_new_child {
                           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");
       $pwdcorrect=        $pwdcorrect=
   (crypt($upass,$contentpwd) eq $contentpwd);    (crypt($upass,$contentpwd) eq $contentpwd);
                           } elsif ($howpwd eq 'unix') {                            } elsif ($howpwd eq 'unix') {
                               $contentpwd=(getpwnam($uname))[1];        &Debug("Unix auth");
       my $pwauth_path="/usr/local/sbin/pwauth";                                if((getpwnam($uname))[1] eq "") { #no such user!
       unless ($contentpwd eq 'x') {    $pwdcorrect = 0;
   $pwdcorrect=        } else {
                                     (crypt($upass,$contentpwd) eq $contentpwd);    $contentpwd=(getpwnam($uname))[1];
       }    my $pwauth_path="/usr/local/sbin/pwauth";
     unless ($contentpwd eq 'x') {
         $pwdcorrect=
     (crypt($upass,$contentpwd) eq 
      $contentpwd);
     }
     
       elsif (-e $pwauth_path) {        elsif (-e $pwauth_path) {
   open PWAUTH, "|$pwauth_path" or    open PWAUTH, "|$pwauth_path" or
       die "Cannot invoke authentication";        die "Cannot invoke authentication";
Line 645  sub make_new_child { Line 723  sub make_new_child {
   close PWAUTH;    close PWAUTH;
   $pwdcorrect=!$?;    $pwdcorrect=!$?;
       }        }
         }
                           } elsif ($howpwd eq 'krb4') {                            } elsif ($howpwd eq 'krb4') {
                              $null=pack("C",0);                                $null=pack("C",0);
      unless ($upass=~/$null/) {                                unless ($upass=~/$null/) {
                               $pwdcorrect=(                                    my $krb4_error = &Authen::Krb4::get_pw_in_tkt
                                  Authen::Krb4::get_pw_in_tkt($uname,"",                                        ($uname,"",$contentpwd,'krbtgt',
                                         $contentpwd,'krbtgt',$contentpwd,1,                                         $contentpwd,1,$upass);
      $upass) == 0);                                    if (!$krb4_error) {
      } else { $pwdcorrect=0; }                                        $pwdcorrect = 1;
                                     } else { 
                                         $pwdcorrect=0; 
                                         # log error if it is not a bad password
                                         if ($krb4_error != 62) {
          &logthis('krb4:'.$uname.','.$contentpwd.','.
                   &Authen::Krb4::get_err_txt($Authen::Krb4::error));
                                         }
                                     }
                                 }
                             } elsif ($howpwd eq 'krb5') {
         $null=pack("C",0);
         unless ($upass=~/$null/) {
     my $krbclient=&Authen::Krb5::parse_name($uname.'@'.$contentpwd);
     my $krbservice="krbtgt/".$contentpwd."\@".$contentpwd;
     my $krbserver=&Authen::Krb5::parse_name($krbservice);
     my $credentials=&Authen::Krb5::cc_default();
     $credentials->initialize($krbclient);
     my $krbreturn = 
       &Authen::Krb5::get_in_tkt_with_password(
        $krbclient,$krbserver,$upass,$credentials);
   #  unless ($krbreturn) {
   #      &logthis("Krb5 Error: ".
   #       &Authen::Krb5::error());
   #  }
     $pwdcorrect = ($krbreturn == 1);
      } else { $pwdcorrect=0; }
                           } elsif ($howpwd eq 'localauth') {                            } elsif ($howpwd eq 'localauth') {
     $pwdcorrect=&localauth::localauth($uname,$upass,      $pwdcorrect=&localauth::localauth($uname,$upass,
       $contentpwd);        $contentpwd);
Line 676  sub make_new_child { Line 781  sub make_new_child {
                        chomp($npass);                         chomp($npass);
                        $upass=&unescape($upass);                         $upass=&unescape($upass);
                        $npass=&unescape($npass);                         $npass=&unescape($npass);
        &logthis("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) {
Line 686  sub make_new_child { Line 791  sub make_new_child {
                           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");
    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);
Line 702  sub make_new_child { Line 808  sub make_new_child {
       # 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");
       $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";
Line 713  sub make_new_child { Line 820  sub make_new_child {
       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=!$?;    &Debug("exited pwauth with $? ($uname,$upass) ");
     $pwdcorrect=($? == 0);
       }        }
      if ($pwdcorrect) {       if ($pwdcorrect) {
  my $execdir=$perlvar{'lonDaemons'};   my $execdir=$perlvar{'lonDaemons'};
  my $pf = IO::File->new("|$execdir/lcpasswd");   &Debug("Opening lcpasswd pipeline");
    my $pf = IO::File->new("|$execdir/lcpasswd > /home/www/lcpasswd.log");
  print $pf "$uname\n$npass\n$npass\n";   print $pf "$uname\n$npass\n$npass\n";
  close $pf;   close $pf;
  my $result = ($?>0 ? 'pwchange_failure'    my $err = $?;
    my $result = ($err>0 ? 'pwchange_failure' 
        : 'ok');         : 'ok');
  &logthis("Result of password change for $uname: $result");   &logthis("Result of password change for $uname: ".
     &lcpasswdstrerror($?));
  print $client "$result\n";   print $client "$result\n";
      } else {       } else {
  print $client "non_authorized\n";   print $client "non_authorized\n";
Line 738  sub make_new_child { Line 849  sub make_new_child {
      }       }
 # -------------------------------------------------------------------- makeuser  # -------------------------------------------------------------------- makeuser
                    } elsif ($userinput =~ /^makeuser/) {                     } elsif ($userinput =~ /^makeuser/) {
      Debug("Make user received");       &Debug("Make user received");
                 my $oldumask=umask(0077);                  my $oldumask=umask(0077);
      if ($wasenc==1) {       if ($wasenc==1) {
                        my                          my 
Line 753  sub make_new_child { Line 864  sub make_new_child {
     $passfilename);      $passfilename);
                        if (-e $passfilename) {                         if (-e $passfilename) {
    print $client "already_exists\n";     print $client "already_exists\n";
                        } elsif ($udom ne $perlvar{'lonDefDomain'}) {                         } elsif ($udom ne $currentdomainid) {
                            print $client "not_right_domain\n";                             print $client "not_right_domain\n";
                        } else {                         } else {
                            @fpparts=split(/\//,$proname);                             @fpparts=split(/\//,$proname);
Line 763  sub make_new_child { Line 874  sub make_new_child {
                                $fpnow.='/'.$fpparts[$i];                                  $fpnow.='/'.$fpparts[$i]; 
                                unless (-e $fpnow) {                                 unless (-e $fpnow) {
    unless (mkdir($fpnow,0777)) {     unless (mkdir($fpnow,0777)) {
                                       $fperror="error:$!";                                        $fperror="error: ".($!+0)
     ." mkdir failed while attempting "
                                                 ."makeuser\n";
                                    }                                     }
                                }                                 }
                            }                             }
                            unless ($fperror) {                             unless ($fperror) {
      if ($umode eq 'krb4') {         my $result=&make_passwd_file($uname, $umode,$npass,
                                {       $passfilename);
                                  my $pf = IO::File->new(">$passfilename");         print $client $result;
             print $pf "krb4:$npass\n";   
                                }               
                                print $client "ok\n";  
                              } elsif ($umode eq 'internal') {  
        my $salt=time;  
                                $salt=substr($salt,6,2);  
        my $ncpass=crypt($npass,$salt);  
                                {   
  &Debug("Creating internal auth");  
  my $pf = IO::File->new(">$passfilename");  
             print $pf "internal:$ncpass\n";   
                                }  
                                print $client "ok\n";  
      } elsif ($umode eq 'localauth') {  
        {  
  my $pf = IO::File->new(">$passfilename");  
             print $pf "localauth:$npass\n";  
        }  
        print $client "ok\n";  
      } elsif ($umode eq 'unix') {  
        {  
  my $execpath="$perlvar{'lonDaemons'}/".  
               "lcuseradd";  
  {  
      &Debug("Executing external: ".  
   $execpath);  
      my $se = IO::File->new("|$execpath");  
      print $se "$uname\n";  
      print $se "$npass\n";  
      print $se "$npass\n";  
  }  
                                  my $pf = IO::File->new(">$passfilename");  
             print $pf "unix:\n";   
        }  
        print $client "ok\n";  
      } elsif ($umode eq 'none') {  
                                {   
                                  my $pf = IO::File->new(">$passfilename");  
             print $pf "none:\n";   
                                }               
                                print $client "ok\n";  
                              } else {  
                                print $client "auth_mode_error\n";  
                              }    
                            } else {                             } else {
                                print $client "$fperror\n";                                 print $client "$fperror\n";
                            }                             }
Line 828  sub make_new_child { Line 897  sub make_new_child {
        &Debug("Changing authorization");         &Debug("Changing authorization");
       if ($wasenc==1) {        if ($wasenc==1) {
                        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 $perlvar{'lonDefDomain'}) {         if ($udom ne $currentdomainid) {
                            print $client "not_right_domain\n";                             print $client "not_right_domain\n";
                        } else {                         } else {
    if ($umode eq 'krb4') {     my $result=&make_passwd_file($uname, $umode,$npass,
                                {    $passfilename);
    my $pf = IO::File->new(">$passfilename");     print $client $result;
    print $pf "krb4:$npass\n";   
                                }               
                                print $client "ok\n";  
    } elsif ($umode eq 'internal') {  
        my $salt=time;  
                                $salt=substr($salt,6,2);  
        my $ncpass=crypt($npass,$salt);  
                                {   
    my $pf = IO::File->new(">$passfilename");  
    print $pf "internal:$ncpass\n";   
                                }  
                                print $client "ok\n";  
    } elsif ($umode eq 'localauth') {  
        {  
    my $pf = IO::File->new(">$passfilename");  
    print $pf "localauth:$npass\n";  
        }  
        print $client "ok\n";  
    } elsif ($umode eq 'unix') {  
        {  
    my $execpath="$perlvar{'lonDaemons'}/".  
        "lcuseradd";  
    {  
        my $se = IO::File->new("|$execpath");  
        print $se "$uname\n";  
        print $se "$npass\n";  
        print $se "$npass\n";  
    }  
    my $pf = IO::File->new(">$passfilename");  
    print $pf "unix:\n";   
        }  
        print $client "ok\n";  
    } elsif ($umode eq 'none') {  
                                {   
    my $pf = IO::File->new(">$passfilename");  
    print $pf "none:\n";   
                                }               
                                print $client "ok\n";  
    } else {  
                                print $client "auth_mode_error\n";  
    }    
                        }                         }
      } else {       } else {
        print $client "refused\n";         print $client "refused\n";
Line 948  sub make_new_child { Line 976  sub make_new_child {
        } else {         } else {
  print $client "rejected\n";   print $client "rejected\n";
                        }                         }
   # -------------------------------------- fetch a user file from a remote server
                      } elsif ($userinput =~ /^fetchuserfile/) {
                         my ($cmd,$fname)=split(/:/,$userinput);
         my ($udom,$uname,$ufile)=split(/\//,$fname);
                         my $udir=propath($udom,$uname).'/userfiles';
                         unless (-e $udir) { mkdir($udir,0770); }
                          if (-e $udir) {
                          $ufile=~s/^[\.\~]+//;
                          $ufile=~s/\///g;
                          my $transname=$udir.'/'.$ufile;
                          my $remoteurl='http://'.$clientip.'/userfiles/'.$fname;
                                my $response;
                                 {
                                my $ua=new LWP::UserAgent;
                                my $request=new HTTP::Request('GET',"$remoteurl");
                                $response=$ua->request($request,$transname);
         }
                                if ($response->is_error()) {
    unlink($transname);
                                    my $message=$response->status_line;
                                    &logthis(
                                     "LWP GET: $message for $fname ($remoteurl)");
    print $client "failed\n";
                                } else {
                                    print $client "ok\n";
                                }
                        } else {
                          print $client "not_home\n";
                        } 
   # ------------------------------------------ authenticate access to a user file
                      } elsif ($userinput =~ /^tokenauthuserfile/) {
                          my ($cmd,$fname,$session)=split(/:/,$userinput);
                          chomp($session);
                          $reply='non_auth';
                          if (open(ENVIN,$perlvar{'lonIDsDir'}.'/'.
                                         $session.'.id')) {
                           while ($line=<ENVIN>) {
      if ($line=~/userfile\.$fname\=/) { $reply='ok'; }
                           }
                           close(ENVIN);
                           print $client $reply."\n";
          } else {
    print $client "invalid_token\n";
                          }
 # ----------------------------------------------------------------- unsubscribe  # ----------------------------------------------------------------- unsubscribe
                    } elsif ($userinput =~ /^unsub/) {                     } elsif ($userinput =~ /^unsub/) {
                        my ($cmd,$fname)=split(/:/,$userinput);                         my ($cmd,$fname)=split(/:/,$userinput);
                        if (-e $fname) {                         if (-e $fname) {
                            if (unlink("$fname.$hostid{$clientip}")) {     print $client &unsub($client,$fname,$clientip);
                               print $client "ok\n";  
    } else {  
                               print $client "not_subscribed\n";  
    }  
                        } else {                         } else {
    print $client "not_found\n";     print $client "not_found\n";
                        }                         }
 # ------------------------------------------------------------------- subscribe  # ------------------------------------------------------------------- subscribe
                    } elsif ($userinput =~ /^sub/) {                     } elsif ($userinput =~ /^sub/) {
          print $client &subscribe($userinput,$clientip);
   # ------------------------------------------------------------- current version
                      } elsif ($userinput =~ /^currentversion/) {
                        my ($cmd,$fname)=split(/:/,$userinput);                         my ($cmd,$fname)=split(/:/,$userinput);
                        my $ownership=ishome($fname);         print $client &currentversion($fname)."\n";
                        if ($ownership eq 'owner') {  
                         if (-e $fname) {  
  if (-d $fname) {  
    print $client "directory\n";  
                          } else {  
                            $now=time;  
                            {   
     my $sh;  
                             if ($sh=  
                              IO::File->new(">$fname.$hostid{$clientip}")) {  
                                print $sh "$clientip:$now\n";  
     }  
    }  
                            unless ($fname=~/\.meta$/) {  
        unlink("$fname.meta.$hostid{$clientip}");  
                            }  
                            $fname=~s/\/home\/httpd\/html\/res/raw/;  
                            $fname="http://$thisserver/".$fname;  
                            print $client "$fname\n";  
          }  
                         } else {  
          print $client "not_found\n";  
                         }  
        } else {  
                         print $client "rejected\n";  
        }  
 # ------------------------------------------------------------------------- log  # ------------------------------------------------------------------------- log
                    } elsif ($userinput =~ /^log/) {                     } elsif ($userinput =~ /^log/) {
                        my ($cmd,$udom,$uname,$what)=split(/:/,$userinput);                         my ($cmd,$udom,$uname,$what)=split(/:/,$userinput);
Line 1002  sub make_new_child { Line 1047  sub make_new_child {
                             print $hfh "$now:$hostid{$clientip}:$what\n";                              print $hfh "$now:$hostid{$clientip}:$what\n";
                             print $client "ok\n";                               print $client "ok\n"; 
  } else {   } else {
                             print $client "error:$!\n";                              print $client "error: ".($!+0)
    ." IO::File->new Failed "
                                       ."while attempting log\n";
         }          }
        }         }
 # ------------------------------------------------------------------------- put  # ------------------------------------------------------------------------- put
Line 1022  sub make_new_child { Line 1069  sub make_new_child {
        ) { print $hfh "P:$now:$what\n"; }         ) { print $hfh "P:$now:$what\n"; }
        }         }
                        my @pairs=split(/\&/,$what);                         my @pairs=split(/\&/,$what);
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                            foreach $pair (@pairs) {                             foreach $pair (@pairs) {
        ($key,$value)=split(/=/,$pair);         ($key,$value)=split(/=/,$pair);
                                $hash{$key}=$value;                                 $hash{$key}=$value;
Line 1030  sub make_new_child { Line 1077  sub make_new_child {
    if (untie(%hash)) {     if (untie(%hash)) {
                               print $client "ok\n";                                print $client "ok\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) failed ".
                                         "while attempting put\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!)
          ." tie(GDBM) Failed ".
                                      "while attempting put\n";
                        }                         }
       } else {        } else {
                           print $client "refused\n";                            print $client "refused\n";
Line 1060  sub make_new_child { Line 1111  sub make_new_child {
                                  }                                   }
        }         }
                        my @pairs=split(/\&/,$what);                         my @pairs=split(/\&/,$what);
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                            foreach $pair (@pairs) {                             foreach $pair (@pairs) {
        ($key,$value)=split(/=/,$pair);         ($key,$value)=split(/=/,$pair);
        &ManagePermissions($key, $udom, $uname,         &ManagePermissions($key, $udom, $uname,
Line 1072  sub make_new_child { Line 1123  sub make_new_child {
    if (untie(%hash)) {     if (untie(%hash)) {
                               print $client "ok\n";                                print $client "ok\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting rolesput\n";
                              }
                          } else {
                              print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting rolesput\n";
                          }
         } else {
                             print $client "refused\n";
                         }
   # -------------------------------------------------------------------- rolesdel
                      } elsif ($userinput =~ /^rolesdel/) {
          &Debug("rolesdel");
       if ($wasenc==1) {
                          my ($cmd,$exedom,$exeuser,$udom,$uname,$what)
                             =split(/:/,$userinput);
          &Debug("cmd = ".$cmd." exedom= ".$exedom.
       "user = ".$exeuser." udom=".$udom.
       "what = ".$what);
                          my $namespace='roles';
                          chomp($what);
                          my $proname=propath($udom,$uname);
                          my $now=time;
                          {
      my $hfh;
      if (
                                $hfh=IO::File->new(">>$proname/$namespace.hist")
          ) { 
                                     print $hfh "D:$now:$exedom:$exeuser:$what\n";
                                    }
          }
                          my @rolekeys=split(/\&/,$what);
         if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                              foreach $key (@rolekeys) {
                                  delete $hash{$key};
          
                              }
      if (untie(%hash)) {
                                 print $client "ok\n";
                              } else {
                                 print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting rolesdel\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting rolesdel\n";
                        }                         }
       } else {        } else {
                           print $client "refused\n";                            print $client "refused\n";
Line 1090  sub make_new_child { Line 1187  sub make_new_child {
                        my @queries=split(/\&/,$what);                         my @queries=split(/\&/,$what);
                        my $proname=propath($udom,$uname);                         my $proname=propath($udom,$uname);
                        my $qresult='';                         my $qresult='';
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                            for ($i=0;$i<=$#queries;$i++) {                             for ($i=0;$i<=$#queries;$i++) {
                                $qresult.="$hash{$queries[$i]}&";                                 $qresult.="$hash{$queries[$i]}&";
                            }                             }
Line 1098  sub make_new_child { Line 1195  sub make_new_child {
               $qresult=~s/\&$//;                $qresult=~s/\&$//;
                               print $client "$qresult\n";                                print $client "$qresult\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting get\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             if ($!+0 == 2) {
                                  print $client "error:No such file or ".
                                      "GDBM reported bad block error\n";
                              } else {
                                  print $client "error: ".($!+0)
                                      ." tie(GDBM) Failed ".
                                          "while attempting get\n";
                              }
                        }                         }
 # ------------------------------------------------------------------------ eget  # ------------------------------------------------------------------------ eget
                    } elsif ($userinput =~ /^eget/) {                     } elsif ($userinput =~ /^eget/) {
Line 1113  sub make_new_child { Line 1219  sub make_new_child {
                        my @queries=split(/\&/,$what);                         my @queries=split(/\&/,$what);
                        my $proname=propath($udom,$uname);                         my $proname=propath($udom,$uname);
                        my $qresult='';                         my $qresult='';
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                            for ($i=0;$i<=$#queries;$i++) {                             for ($i=0;$i<=$#queries;$i++) {
                                $qresult.="$hash{$queries[$i]}&";                                 $qresult.="$hash{$queries[$i]}&";
                            }                             }
Line 1134  sub make_new_child { Line 1240  sub make_new_child {
         print $client "error:no_key\n";          print $client "error:no_key\n";
                               }                                }
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting eget\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting eget\n";
                        }                         }
 # ------------------------------------------------------------------------- del  # ------------------------------------------------------------------------- del
                    } elsif ($userinput =~ /^del/) {                     } elsif ($userinput =~ /^del/) {
Line 1155  sub make_new_child { Line 1265  sub make_new_child {
        ) { print $hfh "D:$now:$what\n"; }         ) { print $hfh "D:$now:$what\n"; }
        }         }
                        my @keys=split(/\&/,$what);                         my @keys=split(/\&/,$what);
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                            foreach $key (@keys) {                             foreach $key (@keys) {
                                delete($hash{$key});                                 delete($hash{$key});
                            }                             }
    if (untie(%hash)) {     if (untie(%hash)) {
                               print $client "ok\n";                                print $client "ok\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting del\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting del\n";
                        }                         }
 # ------------------------------------------------------------------------ keys  # ------------------------------------------------------------------------ keys
                    } elsif ($userinput =~ /^keys/) {                     } elsif ($userinput =~ /^keys/) {
Line 1175  sub make_new_child { Line 1289  sub make_new_child {
                        $namespace=~s/\W//g;                         $namespace=~s/\W//g;
                        my $proname=propath($udom,$uname);                         my $proname=propath($udom,$uname);
                        my $qresult='';                         my $qresult='';
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                            foreach $key (keys %hash) {                             foreach $key (keys %hash) {
                                $qresult.="$key&";                                 $qresult.="$key&";
                            }                             }
Line 1183  sub make_new_child { Line 1297  sub make_new_child {
               $qresult=~s/\&$//;                $qresult=~s/\&$//;
                               print $client "$qresult\n";                                print $client "$qresult\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting keys\n";
                              }
                          } else {
                              print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting keys\n";
                          }
   # ----------------------------------------------------------------- dumpcurrent
                      } elsif ($userinput =~ /^currentdump/) {
                          my ($cmd,$udom,$uname,$namespace)
                             =split(/:/,$userinput);
                          $namespace=~s/\//\_/g;
                          $namespace=~s/\W//g;
                          my $qresult='';
                          my $proname=propath($udom,$uname);
                          if (tie(%hash,'GDBM_File',
                                  "$proname/$namespace.db",
                                  &GDBM_READER(),0640)) {
                              # Structure of %data:
                              # $data{$symb}->{$parameter}=$value;
                              # $data{$symb}->{'v.'.$parameter}=$version;
                              # since $parameter will be unescaped, we do not
                              # have to worry about silly parameter names...
                              my %data = ();
                              while (my ($key,$value) = each(%hash)) {
                                 my ($v,$symb,$param) = split(/:/,$key);
                                 next if ($v eq 'version' || $symb eq 'keys');
                                 next if (exists($data{$symb}) && 
                                          exists($data{$symb}->{$param}) &&
                                          $data{$symb}->{'v.'.$param} > $v);
                                 $data{$symb}->{$param}=$value;
                                 $data{$symb}->{'v.'.$param}=$v;
                              }
                              if (untie(%hash)) {
                                while (my ($symb,$param_hash) = each(%data)) {
                                  while(my ($param,$value) = each (%$param_hash)){
                                    next if ($param =~ /^v\./);
                                    $qresult.=$symb.':'.$param.'='.$value.'&';
                                  }
                                }
                                chop($qresult);
                                print $client "$qresult\n";
                              } else {
                                print $client "error: ".($!+0)
    ." untie(GDBM) Failed ".
                                        "while attempting currentdump\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                         "while attempting currentdump\n";
                        }                         }
 # ------------------------------------------------------------------------ dump  # ------------------------------------------------------------------------ dump
                    } elsif ($userinput =~ /^dump/) {                     } elsif ($userinput =~ /^dump/) {
Line 1199  sub make_new_child { Line 1362  sub make_new_child {
        } else {         } else {
                           $regexp='.';                            $regexp='.';
        }         }
                        my $proname=propath($udom,$uname);  
                        my $qresult='';                         my $qresult='';
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER,0640)) {                         my $proname=propath($udom,$uname);
                            foreach $key (keys %hash) {      if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                                if (eval('$key=~/$regexp/')) {                             study($regexp);
                                   $qresult.="$key=$hash{$key}&";                             while (($key,$value) = each(%hash)) {
        }                                 if ($regexp eq '.') {
                                      $qresult.=$key.'='.$value.'&';
                                  } else {
                                      my $unescapeKey = &unescape($key);
                                      if (eval('$unescapeKey=~/$regexp/')) {
                                          $qresult.="$key=$value&";
                                      }
                                  }
                            }                             }
    if (untie(%hash)) {                             if (untie(%hash)) {
               $qresult=~s/\&$//;                                 chop($qresult);
                               print $client "$qresult\n";                                 print $client "$qresult\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                 print $client "error: ".($!+0)
      ." untie(GDBM) Failed ".
                                          "while attempting dump\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                         "while attempting dump\n";
                        }                         }
 # ----------------------------------------------------------------------- store  # ----------------------------------------------------------------------- store
                    } elsif ($userinput =~ /^store/) {                     } elsif ($userinput =~ /^store/) {
Line 1234  sub make_new_child { Line 1407  sub make_new_child {
        }         }
                        my @pairs=split(/\&/,$what);                         my @pairs=split(/\&/,$what);
                                                     
     if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT,0640)) {      if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_WRCREAT(),0640)) {
                            my @previouskeys=split(/&/,$hash{"keys:$rid"});                             my @previouskeys=split(/&/,$hash{"keys:$rid"});
                            my $key;                             my $key;
                            $hash{"version:$rid"}++;                             $hash{"version:$rid"}++;
Line 1251  sub make_new_child { Line 1424  sub make_new_child {
    if (untie(%hash)) {     if (untie(%hash)) {
                               print $client "ok\n";                                print $client "ok\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting store\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting store\n";
                        }                         }
       } else {        } else {
                           print $client "refused\n";                            print $client "refused\n";
Line 1268  sub make_new_child { Line 1445  sub make_new_child {
                        chomp($rid);                         chomp($rid);
                        my $proname=propath($udom,$uname);                         my $proname=propath($udom,$uname);
                        my $qresult='';                         my $qresult='';
       if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER,0640)) {        if (tie(%hash,'GDBM_File',"$proname/$namespace.db",&GDBM_READER(),0640)) {
                   my $version=$hash{"version:$rid"};                    my $version=$hash{"version:$rid"};
                            $qresult.="version=$version&";                             $qresult.="version=$version&";
                            my $scope;                             my $scope;
Line 1285  sub make_new_child { Line 1462  sub make_new_child {
               $qresult=~s/\&$//;                $qresult=~s/\&$//;
                               print $client "$qresult\n";                                print $client "$qresult\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting restore\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting restore\n";
                        }                         }
   # -------------------------------------------------------------------- chatsend
                      } elsif ($userinput =~ /^chatsend/) {
                          my ($cmd,$cdom,$cnum,$newpost)=split(/\:/,$userinput);
                          &chatadd($cdom,$cnum,$newpost);
                          print $client "ok\n";
   # -------------------------------------------------------------------- chatretr
                      } elsif ($userinput =~ /^chatretr/) {
                          my 
                           ($cmd,$cdom,$cnum,$udom,$uname)=split(/\:/,$userinput);
                          my $reply='';
                          foreach (&getchat($cdom,$cnum,$udom,$uname)) {
      $reply.=&escape($_).':';
                          }
                          $reply=~s/\:$//;
                          print $client $reply."\n";
 # ------------------------------------------------------------------- querysend  # ------------------------------------------------------------------- querysend
                    } elsif ($userinput =~ /^querysend/) {                     } elsif ($userinput =~ /^querysend/) {
                        my ($cmd,$query,                         my ($cmd,$query,
    $custom,$customshow)=split(/:/,$userinput);     $arg1,$arg2,$arg3)=split(/\:/,$userinput);
        $query=~s/\n*$//g;         $query=~s/\n*$//g;
        unless ($custom or $customshow) {         print $client "".
    print $client "".  
        sqlreply("$hostid{$clientip}\&$query")."\n";  
        }  
        else {  
    print $client "".  
        sqlreply("$hostid{$clientip}\&$query".         sqlreply("$hostid{$clientip}\&$query".
  "\&$custom"."\&$customshow")."\n";   "\&$arg1"."\&$arg2"."\&$arg3")."\n";
        }  
 # ------------------------------------------------------------------ queryreply  # ------------------------------------------------------------------ queryreply
                    } elsif ($userinput =~ /^queryreply/) {                     } elsif ($userinput =~ /^queryreply/) {
                        my ($cmd,$id,$reply)=split(/:/,$userinput);                          my ($cmd,$id,$reply)=split(/:/,$userinput); 
Line 1319  sub make_new_child { Line 1509  sub make_new_child {
    print $client "ok\n";     print $client "ok\n";
        }         }
        else {         else {
    print $client "error:$!\n";     print $client "error: ".($!+0)
          ." IO::File->new Failed ".
                                      "while attempting queryreply\n";
          }
   # ----------------------------------------------------------------- courseidput
                      } elsif ($userinput =~ /^courseidput/) {
                          my ($cmd,$udom,$what)=split(/:/,$userinput);
                          chomp($what);
                          $udom=~s/\W//g;
                          my $proname=
                                 "$perlvar{'lonUsersDir'}/$udom/nohist_courseids";
                          my $now=time;
                          my @pairs=split(/\&/,$what);
                    if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) {
                              foreach $pair (@pairs) {
          ($key,$value)=split(/=/,$pair);
                                  $hash{$key}=$value.':'.$now;
                              }
      if (untie(%hash)) {
                                 print $client "ok\n";
                              } else {
                                 print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting courseidput\n";
                              }
                          } else {
                              print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                         "while attempting courseidput\n";
                          }
   # ---------------------------------------------------------------- courseiddump
                      } elsif ($userinput =~ /^courseiddump/) {
                          my ($cmd,$udom,$since,$description)
                             =split(/:/,$userinput);
                          if (defined($description)) {
                             $description=&unescape($description);
          } else {
                             $description='.';
        }         }
                          unless (defined($since)) { $since=0; }
                          my $qresult='';
                          my $proname=
                                 "$perlvar{'lonUsersDir'}/$udom/nohist_courseids";
                   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) {
                              while (($key,$value) = each(%hash)) {
                                  my ($descr,$lasttime)=split(/\:/,$value);
                                  if ($lasttime<$since) { next; }
                                  if ($regexp eq '.') {
                                      $qresult.=$key.'='.$descr.'&';
                                  } else {
                                      my $unescapeVal = &unescape($descr);
                                      if (eval('$unescapeVal=~/$description/i')) {
                                          $qresult.="$key=$descr&";
                                      }
                                  }
                              }
                              if (untie(%hash)) {
                                  chop($qresult);
                                  print $client "$qresult\n";
                              } else {
                                  print $client "error: ".($!+0)
      ." untie(GDBM) Failed ".
                                          "while attempting courseiddump\n";
                              }
                          } else {
                              print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                         "while attempting courseiddump\n";
                          }
 # ----------------------------------------------------------------------- idput  # ----------------------------------------------------------------------- idput
                    } elsif ($userinput =~ /^idput/) {                     } elsif ($userinput =~ /^idput/) {
                        my ($cmd,$udom,$what)=split(/:/,$userinput);                         my ($cmd,$udom,$what)=split(/:/,$userinput);
Line 1335  sub make_new_child { Line 1592  sub make_new_child {
        ) { print $hfh "P:$now:$what\n"; }         ) { print $hfh "P:$now:$what\n"; }
        }         }
                        my @pairs=split(/\&/,$what);                         my @pairs=split(/\&/,$what);
                  if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT,0640)) {                   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_WRCREAT(),0640)) {
                            foreach $pair (@pairs) {                             foreach $pair (@pairs) {
        ($key,$value)=split(/=/,$pair);         ($key,$value)=split(/=/,$pair);
                                $hash{$key}=$value;                                 $hash{$key}=$value;
Line 1343  sub make_new_child { Line 1600  sub make_new_child {
    if (untie(%hash)) {     if (untie(%hash)) {
                               print $client "ok\n";                                print $client "ok\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting idput\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                         "while attempting idput\n";
                        }                         }
 # ----------------------------------------------------------------------- idget  # ----------------------------------------------------------------------- idget
                    } elsif ($userinput =~ /^idget/) {                     } elsif ($userinput =~ /^idget/) {
Line 1356  sub make_new_child { Line 1617  sub make_new_child {
                        my $proname="$perlvar{'lonUsersDir'}/$udom/ids";                         my $proname="$perlvar{'lonUsersDir'}/$udom/ids";
                        my @queries=split(/\&/,$what);                         my @queries=split(/\&/,$what);
                        my $qresult='';                         my $qresult='';
                  if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER,0640)) {                   if (tie(%hash,'GDBM_File',"$proname.db",&GDBM_READER(),0640)) {
                            for ($i=0;$i<=$#queries;$i++) {                             for ($i=0;$i<=$#queries;$i++) {
                                $qresult.="$hash{$queries[$i]}&";                                 $qresult.="$hash{$queries[$i]}&";
                            }                             }
Line 1364  sub make_new_child { Line 1625  sub make_new_child {
               $qresult=~s/\&$//;                $qresult=~s/\&$//;
                               print $client "$qresult\n";                                print $client "$qresult\n";
                            } else {                             } else {
                               print $client "error:$!\n";                                print $client "error: ".($!+0)
     ." untie(GDBM) Failed ".
                                         "while attempting idget\n";
                            }                             }
                        } else {                         } else {
                            print $client "error:$!\n";                             print $client "error: ".($!+0)
          ." tie(GDBM) Failed ".
                                      "while attempting idget\n";
                        }                         }
 # ---------------------------------------------------------------------- tmpput  # ---------------------------------------------------------------------- tmpput
                    } elsif ($userinput =~ /^tmpput/) {                     } elsif ($userinput =~ /^tmpput/) {
Line 1384  sub make_new_child { Line 1649  sub make_new_child {
    print $client "$id\n";     print $client "$id\n";
        }         }
        else {         else {
    print $client "error:$!\n";     print $client "error: ".($!+0)
          ."IO::File->new Failed ".
                                      "while attempting tmpput\n";
        }         }
   
 # ---------------------------------------------------------------------- tmpget  # ---------------------------------------------------------------------- tmpget
Line 1400  sub make_new_child { Line 1667  sub make_new_child {
                            close $store;                             close $store;
        }         }
        else {         else {
    print $client "error:$!\n";     print $client "error: ".($!+0)
          ."IO::File->new Failed ".
                                      "while attempting tmpget\n";
        }         }
   
   # ---------------------------------------------------------------------- tmpdel
                      } elsif ($userinput =~ /^tmpdel/) {
                          my ($cmd,$id)=split(/:/,$userinput);
                          chomp($id);
                          $id=~s/\W/\_/g;
                          my $execdir=$perlvar{'lonDaemons'};
                          if (unlink("$execdir/tmp/$id.tmp")) {
      print $client "ok\n";
          } else {
      print $client "error: ".($!+0)
          ."Unlink tmp Failed ".
                                      "while attempting tmpdel\n";
          }
 # -------------------------------------------------------------------------- ls  # -------------------------------------------------------------------------- ls
                    } elsif ($userinput =~ /^ls/) {                     } elsif ($userinput =~ /^ls/) {
                        my ($cmd,$ulsdir)=split(/:/,$userinput);                         my ($cmd,$ulsdir)=split(/:/,$userinput);
                        my $ulsout='';                         my $ulsout='';
                        my $ulsfn;                         my $ulsfn;
                        if (-e $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.'&'.join('&',@ulsstats).':';                                         my @ulsstats=stat($ulsdir.'/'.$ulsfn);
                           }                                         $ulsout.=$ulsfn.'&'.
                           closedir(LSDIR);                                                  join('&',@ulsstats).':';
         }                                     }
        } else {                                     closedir(LSDIR);
                                  }
                              } else {
                                  my @ulsstats=stat($ulsdir);
                                  $ulsout.=$ulsfn.'&'.join('&',@ulsstats).':';
                              }
                          } else {
                           $ulsout='no_such_dir';                            $ulsout='no_such_dir';
                        }                         }
                        if ($ulsout eq '') { $ulsout='empty'; }                         if ($ulsout eq '') { $ulsout='empty'; }
Line 1430  sub make_new_child { Line 1718  sub make_new_child {
                        $client->close();                         $client->close();
        last;         last;
 # ------------------------------------------------------------- unknown command  # ------------------------------------------------------------- unknown command
      } elsif ($userinput =~ /^sethost:/) {
          print $client &sethost($userinput)."\n";
      } elsif ($userinput =~/^version:/) {
          print $client &version($userinput)."\n";
                    } else {                     } else {
                        # unknown command                         # unknown command
                        print $client "unknown_cmd\n";                         print $client "unknown_cmd\n";
Line 1445  sub make_new_child { Line 1737  sub make_new_child {
                 &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 ($hostid{$clientip})</font>");    
         # tidy up gracefully and finish  
       
         $server->close();  
   
         # 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 1500  sub GetAuthType Line 1790  sub GetAuthType
     my $domain = shift;      my $domain = shift;
     my $user   = shift;      my $user   = shift;
   
       Debug("GetAuthType( $domain, $user ) \n");
     my $proname    = &propath($domain, $user);       my $proname    = &propath($domain, $user); 
     my $passwdfile = "$proname/passwd";      my $passwdfile = "$proname/passwd";
     if( -e $passwdfile ) {      if( -e $passwdfile ) {
  my $pf = IO::File->new($passwdfile);   my $pf = IO::File->new($passwdfile);
  my $realpassword = <$pf>;   my $realpassword = <$pf>;
  chomp($realpassword);   chomp($realpassword);
    Debug("Password info = $realpassword\n");
  my ($authtype, $contentpwd) = split(/:/, $realpassword);   my ($authtype, $contentpwd) = split(/:/, $realpassword);
    Debug("Authtype = $authtype, content = $contentpwd\n");
  my $availinfo = '';   my $availinfo = '';
  if($authtype eq 'krb4') {   if($authtype eq 'krb4' or $authtype eq 'krb5') {
     $availinfo = $contentpwd;      $availinfo = $contentpwd;
  }   }
   
  return "$authtype:$availinfo";   return "$authtype:$availinfo";
     }      }
     else {      else {
    Debug("Returning nouser");
  return "nouser";   return "nouser";
     }      }
       }
   
   sub addline {
       my ($fname,$hostid,$ip,$newline)=@_;
       my $contents;
       my $found=0;
       my $expr='^'.$hostid.':'.$ip.':';
       $expr =~ s/\./\\\./g;
       if ($sh=IO::File->new("$fname.subscription")) {
    while (my $subline=<$sh>) {
       if ($subline !~ /$expr/) {$contents.= $subline;} else {$found=1;}
    }
    $sh->close();
       }
       $sh=IO::File->new(">$fname.subscription");
       if ($contents) { print $sh $contents; }
       if ($newline) { print $sh $newline; }
       $sh->close();
       return $found;
   }
   
   sub getchat {
       my ($cdom,$cname,$udom,$uname)=@_;
       my %hash;
       my $proname=&propath($cdom,$cname);
       my @entries=();
       if (tie(%hash,'GDBM_File',"$proname/nohist_chatroom.db",
       &GDBM_READER(),0640)) {
    @entries=map { $_.':'.$hash{$_} } sort keys %hash;
    untie %hash;
       }
       my @participants=();
       $cutoff=time-60;
       if (tie(%hash,'GDBM_File',"$proname/nohist_inchatroom.db",
       &GDBM_WRCREAT(),0640)) {
           $hash{$uname.':'.$udom}=time;
           foreach (sort keys %hash) {
       if ($hash{$_}>$cutoff) {
    $participants[$#participants+1]='active_participant:'.$_;
               }
           }
           untie %hash;
       }
       return (@participants,@entries);
   }
   
   sub chatadd {
       my ($cdom,$cname,$newchat)=@_;
       my %hash;
       my $proname=&propath($cdom,$cname);
       my @entries=();
       if (tie(%hash,'GDBM_File',"$proname/nohist_chatroom.db",
       &GDBM_WRCREAT(),0640)) {
    @entries=map { $_.':'.$hash{$_} } sort keys %hash;
    my $time=time;
    my ($lastid)=($entries[$#entries]=~/^(\w+)\:/);
    my ($thentime,$idnum)=split(/\_/,$lastid);
    my $newid=$time.'_000000';
    if ($thentime==$time) {
       $idnum=~s/^0+//;
       $idnum++;
       $idnum=substr('000000'.$idnum,-6,6);
       $newid=$time.'_'.$idnum;
    }
    $hash{$newid}=$newchat;
    my $expired=$time-3600;
    foreach (keys %hash) {
       my ($thistime)=($_=~/(\d+)\_/);
       if ($thistime<$expired) {
    delete $hash{$_};
       }
    }
    untie %hash;
       }
   }
   
   sub unsub {
       my ($fname,$clientip)=@_;
       my $result;
       if (unlink("$fname.$hostid{$clientip}")) {
    $result="ok\n";
       } else {
    $result="not_subscribed\n";
       }
       if (-e "$fname.subscription") {
    my $found=&addline($fname,$hostid{$clientip},$clientip,'');
    if ($found) { $result="ok\n"; }
       } else {
    if ($result != "ok\n") { $result="not_subscribed\n"; }
       }
       return $result;
   }
   
   sub currentversion {
       my $fname=shift;
       my $version=-1;
       my $ulsdir='';
       if ($fname=~/^(.+)\/[^\/]+$/) {
          $ulsdir=$1;
       }
       my ($fnamere1,$fnamere2);
       # remove version if already specified
       $fname=~s/\.\d+\.(\w+(?:\.meta)*)$/\.$1/;
       # get the bits that go before and after the version number
       if ( $fname=~/^(.*\.)(\w+(?:\.meta)*)$/ ) {
    $fnamere1=$1;
    $fnamere2='.'.$2;
       }
       if (-e $fname) { $version=1; }
       if (-e $ulsdir) {
          if(-d $ulsdir) {
             if (opendir(LSDIR,$ulsdir)) {
   
                while ($ulsfn=readdir(LSDIR)) {
   # see if this is a regular file (ignore links produced earlier)
                    my $thisfile=$ulsdir.'/'.$ulsfn;
                    unless (-l $thisfile) {
        if ($thisfile=~/\Q$fnamere1\E(\d+)\Q$fnamere2\E/) {
    if ($1>$version) { $version=$1; }
        }
    }
                }
                closedir(LSDIR);
                $version++;
             }
         }
      }
      return $version;
   }
   
   sub thisversion {
       my $fname=shift;
       my $version=-1;
       if ($fname=~/\.(\d+)\.\w+(?:\.meta)*$/) {
    $version=$1;
       }
       return $version;
   }
   
   sub subscribe {
       my ($userinput,$clientip)=@_;
       my $result;
       my ($cmd,$fname)=split(/:/,$userinput);
       my $ownership=&ishome($fname);
       if ($ownership eq 'owner') {
   # explitly asking for the current version?
           unless (-e $fname) {
               my $currentversion=&currentversion($fname);
       if (&thisversion($fname)==$currentversion) {
                   if ($fname=~/^(.+)\.\d+\.(\w+(?:\.meta)*)$/) {
       my $root=$1;
                       my $extension=$2;
                       symlink($root.'.'.$extension,
                               $root.'.'.$currentversion.'.'.$extension);
                       unless ($extension=~/\.meta$/) {
                          symlink($root.'.'.$extension.'.meta',
                               $root.'.'.$currentversion.'.'.$extension.'.meta');
       }
                   }
               }
           }
    if (-e $fname) {
       if (-d $fname) {
    $result="directory\n";
       } else {
    if (-e "$fname.$hostid{$clientip}") {&unsub($fname,$clientip);}
    $now=time;
    my $found=&addline($fname,$hostid{$clientip},$clientip,
      "$hostid{$clientip}:$clientip:$now\n");
    if ($found) { $result="$fname\n"; }
    # if they were subscribed to only meta data, delete that
                   # subscription, when you subscribe to a file you also get
                   # the metadata
    unless ($fname=~/\.meta$/) { &unsub("$fname.meta",$clientip); }
    $fname=~s/\/home\/httpd\/html\/res/raw/;
    $fname="http://$thisserver/".$fname;
    $result="$fname\n";
       }
    } else {
       $result="not_found\n";
    }
       } else {
    $result="rejected\n";
       }
       return $result;
   }
   
   sub make_passwd_file {
       my ($uname, $umode,$npass,$passfilename)=@_;
       my $result="ok\n";
       if ($umode eq 'krb4' or $umode eq 'krb5') {
    {
       my $pf = IO::File->new(">$passfilename");
       print $pf "$umode:$npass\n";
    }
       } elsif ($umode eq 'internal') {
    my $salt=time;
    $salt=substr($salt,6,2);
    my $ncpass=crypt($npass,$salt);
    {
       &Debug("Creating internal auth");
       my $pf = IO::File->new(">$passfilename");
       print $pf "internal:$ncpass\n"; 
    }
       } elsif ($umode eq 'localauth') {
    {
       my $pf = IO::File->new(">$passfilename");
       print $pf "localauth:$npass\n";
    }
       } elsif ($umode eq 'unix') {
    {
       my $execpath="$perlvar{'lonDaemons'}/"."lcuseradd";
       {
    &Debug("Executing external: ".$execpath);
    &Debug("user  = ".$uname.", Password =". $npass);
    my $se = IO::File->new("|$execpath > /home/www/lcuseradd.log");
    print $se "$uname\n";
    print $se "$npass\n";
    print $se "$npass\n";
       }
       my $useraddok = $?;
       if($useraddok > 0) {
    &logthis("Failed lcuseradd: ".&lcuseraddstrerror($useraddok));
       }
       my $pf = IO::File->new(">$passfilename");
       print $pf "unix:\n";
    }
       } elsif ($umode eq 'none') {
    {
       my $pf = IO::File->new(">$passfilename");
       print $pf "none:\n";
    }
       } else {
    $result="auth_mode_error\n";
       }
       return $result;
   }
   
   sub sethost {
       my ($remotereq) = @_;
       my (undef,$hostid)=split(/:/,$remotereq);
       if (!defined($hostid)) { $hostid=$perlvar{'lonHostID'}; }
       if ($hostip{$perlvar{'lonHostID'}} eq $hostip{$hostid}) {
    $currenthostid=$hostid;
    $currentdomainid=$hostdom{$hostid};
    &logthis("Setting hostid to $hostid, and domain to $currentdomainid");
       } else {
    &logthis("Requested host id $hostid not an alias of ".
    $perlvar{'lonHostID'}." refusing connection");
    return 'unable_to_set';
       }
       return 'ok';
   }
   
   sub version {
       my ($userinput)=@_;
       $remoteVERSION=(split(/:/,$userinput))[1];
       return "version:$VERSION";
   }
   
   #There is a copy of this in lonnet.pm
   sub userload {
       my $numusers=0;
       {
    opendir(LONIDS,$perlvar{'lonIDsDir'});
    my $filename;
    my $curtime=time;
    while ($filename=readdir(LONIDS)) {
       if ($filename eq '.' || $filename eq '..') {next;}
       my ($atime)=(stat($perlvar{'lonIDsDir'}.'/'.$filename))[8];
       if ($curtime-$atime < 3600) { $num_users++; }
    }
    closedir(LONIDS);
       }
       my $userloadpercent=0;
       my $maxuserload=$perlvar{'lonUserLoadLim'};
       if ($maxuserload) {
    $userloadpercent=100*$num_users/$maxuserload;
       }
       return $userloadpercent;
 }  }
   
 # ----------------------------------- POD (plain old documentation, CPAN style)  # ----------------------------------- POD (plain old documentation, CPAN style)
Line 1817  Crypt::IDEA Line 2391  Crypt::IDEA
 LWP::UserAgent()  LWP::UserAgent()
 GDBM_File  GDBM_File
 Authen::Krb4  Authen::Krb4
   Authen::Krb5
   
 =head1 COREQUISITES  =head1 COREQUISITES
   

Removed from v.1.78  
changed lines
  Added in v.1.128


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