--- loncom/lond	2006/10/13 04:23:02	1.344
+++ loncom/lond	2007/04/03 00:49:55	1.368
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # lond "LON Daemon" Server (port "LOND" 5663)
 #
-# $Id: lond,v 1.344 2006/10/13 04:23:02 raeburn Exp $
+# $Id: lond,v 1.368 2007/04/03 00:49:55 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -33,6 +33,7 @@ use strict;
 use lib '/home/httpd/lib/perl/';
 use LONCAPA;
 use LONCAPA::Configuration;
+use Apache::lonnet;
 
 use IO::Socket;
 use IO::File;
@@ -40,16 +41,15 @@ use IO::File;
 use POSIX;
 use Crypt::IDEA;
 use LWP::UserAgent();
+use Digest::MD5 qw(md5_hex);
 use GDBM_File;
 use Authen::Krb4;
 use Authen::Krb5;
-use lib '/home/httpd/lib/perl/';
 use localauth;
 use localenroll;
 use localstudentphoto;
 use File::Copy;
 use File::Find;
-use LONCAPA::ConfigFileEdit;
 use LONCAPA::lonlocal;
 use LONCAPA::lonssl;
 use Fcntl qw(:flock);
@@ -59,7 +59,7 @@ my $DEBUG = 0;		       # Non zero to ena
 my $status='';
 my $lastlog='';
 
-my $VERSION='$Revision: 1.344 $'; #' stupid emacs
+my $VERSION='$Revision: 1.368 $'; #' stupid emacs
 my $remoteVERSION;
 my $currenthostid="default";
 my $currentdomainid;
@@ -85,12 +85,6 @@ my $tmpsnum = 0;		# Id of tmpputs.
 
 my $ConnectionType;
 
-my %hostid;			# ID's for hosts in cluster by ip.
-my %hostdom;			# LonCAPA domain for hosts in cluster.
-my %hostname;			# DNSname -> ID's mapping.
-my %hostip;			# IPs for hosts in cluster.
-my %hostdns;			# ID's of hosts looked up by DNS name.
-
 my %managers;			# Ip -> manager names
 
 my %perlvar;			# Will have the apache conf defined perl vars.
@@ -424,7 +418,7 @@ sub ReadManagerTable {
       if ($host =~ "^#") {                  # Comment line.
          next;
       }
-      if (!defined $hostip{$host}) { # This is a non cluster member
+      if (!defined &Apache::lonnet::get_host_ip($host)) { # This is a non cluster member
 	    #  The entry is of the form:
 	    #    cluname:hostname
 	    #  cluname - A 'cluster hostname' is needed in order to negotiate
@@ -442,7 +436,7 @@ sub ReadManagerTable {
          }
       } else {
          logthis('<font color="green"> existing host'." $host</font>\n");
-         $managers{$hostip{$host}} = $host;  # Use info from cluster tab if clumemeber
+         $managers{&Apache::lonnet::get_host_ip($host)} = $host;  # Use info from cluster tab if clumemeber
       }
    }
 }
@@ -503,30 +497,30 @@ sub AdjustHostContents {
     my $adjusted;
     my $me        = $perlvar{'lonHostID'};
 
- foreach my $line (split(/\n/,$contents)) {
+    foreach my $line (split(/\n/,$contents)) {
 	if(!(($line eq "") || ($line =~ /^ *\#/) || ($line =~ /^ *$/))) {
 	    chomp($line);
 	    my ($id,$domain,$role,$name,$ip,$maxcon,$idleto,$mincon)=split(/:/,$line);
 	    if ($id eq $me) {
-          my $ip = gethostbyname($name);
-          my $ipnew = inet_ntoa($ip);
-         $ip = $ipnew;
+		my $ip = gethostbyname($name);
+		my $ipnew = inet_ntoa($ip);
+		$ip = $ipnew;
 		#  Reconstruct the host line and append to adjusted:
 		
-		   my $newline = "$id:$domain:$role:$name:$ip";
-		   if($maxcon ne "") { # Not all hosts have loncnew tuning params
-		     $newline .= ":$maxcon:$idleto:$mincon";
-		   }
-		   $adjusted .= $newline."\n";
+		my $newline = "$id:$domain:$role:$name:$ip";
+		if($maxcon ne "") { # Not all hosts have loncnew tuning params
+		    $newline .= ":$maxcon:$idleto:$mincon";
+		}
+		$adjusted .= $newline."\n";
 		
-      } else {		# Not me, pass unmodified.
-		   $adjusted .= $line."\n";
-      }
+	    } else {		# Not me, pass unmodified.
+		$adjusted .= $line."\n";
+	    }
 	} else {                  # Blank or comment never re-written.
 	    $adjusted .= $line."\n";	# Pass blanks and comments as is.
 	}
- }
- return $adjusted;
+    }
+    return $adjusted;
 }
 #
 #   InstallFile: Called to install an administrative file:
@@ -1032,7 +1026,7 @@ sub ping_handler {
 sub pong_handler {
     my ($cmd, $tail, $replyfd) = @_;
 
-    my $reply=&reply("ping",$clientname);
+    my $reply=&Apache::lonnet::reply("ping",$clientname);
     &Reply( $replyfd, "$currenthostid:$reply\n", "$cmd:$tail"); 
     return 1;
 }
@@ -1142,7 +1136,7 @@ sub load_handler {
 sub user_load_handler {
     my ($cmd, $tail, $replyfd) = @_;
 
-    my $userloadpercent=&userload();
+    my $userloadpercent=&Apache::lonnet::userload();
     &Reply($replyfd, "$userloadpercent\n", "$cmd:$tail");
     
     return 1;
@@ -1268,6 +1262,7 @@ sub du_handler {
 	my $code=sub { 
 	    if ($_=~/\.\d+\./) { return;} 
 	    if ($_=~/\.meta$/) { return;}
+	    if (-d $_)         { return;}
 	    $total_size+=(stat($_))[7];
 	};
 	chdir($ududir);
@@ -1574,17 +1569,24 @@ sub change_password_handler {
     #  uname - Username.
     #  upass - Current password.
     #  npass - New password.
+    #  context - Context in which this was called 
+    #            (preferences or reset_by_email).
    
-    my ($udom,$uname,$upass,$npass)=split(/:/,$tail);
+    my ($udom,$uname,$upass,$npass,$context)=split(/:/,$tail);
 
     $upass=&unescape($upass);
     $npass=&unescape($npass);
     &Debug("Trying to change password for $uname");
 
     # First require that the user can be authenticated with their
-    # old password:
-
-    my $validated = &validate_user($udom, $uname, $upass);
+    # old password unless context was 'reset_by_email':
+    
+    my $validated;
+    if ($context eq 'reset_by_email') {
+        $validated = 1;
+    } else {
+        $validated = &validate_user($udom, $uname, $upass);
+    }
     if($validated) {
 	my $realpasswd  = &get_auth_type($udom, $uname); # Defined since authd.
 	
@@ -1603,7 +1605,7 @@ sub change_password_handler {
 			 ."to change password");
 		&Failure( $client, "non_authorized\n",$userinput);
 	    }
-	} elsif ($howpwd eq 'unix') {
+	} elsif ($howpwd eq 'unix' && $context ne 'reset_by_email') {
 	    my $result = &change_unix_password($uname, $npass);
 	    &logthis("Result of password change for $uname: ".
 		     $result);
@@ -1842,13 +1844,13 @@ sub update_resource_handler {
 	    my $now=time;
 	    my $since=$now-$atime;
 	    if ($since>$perlvar{'lonExpire'}) {
-		my $reply=&reply("unsub:$fname","$clientname");
+		my $reply=&Apache::lonnet::reply("unsub:$fname","$clientname");
 		&devalidate_meta_cache($fname);
 		unlink("$fname");
 		unlink("$fname.meta");
 	    } else {
 		my $transname="$fname.in.transfer";
-		my $remoteurl=&reply("sub:$fname","$clientname");
+		my $remoteurl=&Apache::lonnet::reply("sub:$fname","$clientname");
 		my $response;
 		alarm(120);
 		{
@@ -1893,22 +1895,12 @@ sub devalidate_meta_cache {
     my ($url) = @_;
     use Cache::Memcached;
     my $memcache = new Cache::Memcached({'servers'=>['127.0.0.1:11211']});
-    $url = &declutter($url);
+    $url = &Apache::lonnet::declutter($url);
     $url =~ s-\.meta$--;
     my $id = &escape('meta:'.$url);
     $memcache->delete($id);
 }
 
-sub declutter {
-    my $thisfn=shift;
-    $thisfn=~s/^\Q$perlvar{'lonDocRoot'}\E//;
-    $thisfn=~s/^\///;
-    $thisfn=~s|^adm/wrapper/||;
-    $thisfn=~s|^adm/coursedocs/showdoc/||;
-    $thisfn=~s/^res\///;
-    $thisfn=~s/\?.+$//;
-    return $thisfn;
-}
 #
 #   Fetch a user file from a remote server to the user's home directory
 #   userfiles subdir.
@@ -3045,10 +3037,10 @@ sub restore_handler {
     my ($cmd, $tail, $client) = @_;
 
     my $userinput = "$cmd:$tail";	# Only used for logging purposes.
-
     my ($udom,$uname,$namespace,$rid) = split(/:/,$tail);
     $namespace=~s/\//\_/g;
-    $namespace=~s/\W//g;
+    $namespace = &LONCAPA::clean_username($namespace);
+
     chomp($rid);
     my $qresult='';
     my $hashref = &tie_user_hash($udom, $uname, $namespace, &GDBM_READER());
@@ -3285,13 +3277,14 @@ sub put_course_id_handler {
 	foreach my $pair (@pairs) {
             my ($key,$courseinfo) = split(/=/,$pair,2);
             $courseinfo =~ s/=/:/g;
-
-            my @current_items = split(/:/,$hashref->{$key});
+            my @current_items = split(/:/,$hashref->{$key},-1);
             shift(@current_items); # remove description
             pop(@current_items);   # remove last access
             my $numcurrent = scalar(@current_items);
-
-            my @new_items = split(/:/,$courseinfo);
+            if ($numcurrent > 3) {
+                $numcurrent = 3;
+            }
+            my @new_items = split(/:/,$courseinfo,-1);
             my $numnew = scalar(@new_items);
             if ($numcurrent > 0) {
                 if ($numnew <= $numcurrent) { # flushcourselogs() from pre 2.2 
@@ -3502,6 +3495,99 @@ sub dump_course_id_handler {
 &register_handler("courseiddump", \&dump_course_id_handler, 0, 1, 0);
 
 #
+# Puts an unencrypted entry in a namespace db file at the domain level 
+#
+# Parameters:
+#    $cmd      - The command that got us here.
+#    $tail     - Tail of the command (remaining parameters).
+#    $client   - File descriptor connected to client.
+# Returns
+#     0        - Requested to exit, caller should shut down.
+#     1        - Continue processing.
+#  Side effects:
+#     reply is written to $client.
+#
+sub put_domain_handler {
+    my ($cmd,$tail,$client) = @_;
+
+    my $userinput = "$cmd:$tail";
+
+    my ($udom,$namespace,$what) =split(/:/,$tail,3);
+    chomp($what);
+    my @pairs=split(/\&/,$what);
+    my $hashref = &tie_domain_hash($udom, "$namespace", &GDBM_WRCREAT(),
+                                   "P", $what);
+    if ($hashref) {
+        foreach my $pair (@pairs) {
+            my ($key,$value)=split(/=/,$pair);
+            $hashref->{$key}=$value;
+        }
+        if (&untie_domain_hash($hashref)) {
+            &Reply($client, "ok\n", $userinput);
+        } else {
+            &Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
+                     "while attempting putdom\n", $userinput);
+        }
+    } else {
+        &Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ".
+                  "while attempting putdom\n", $userinput);
+    }
+
+    return 1;
+}
+&register_handler("putdom", \&put_domain_handler, 0, 1, 0);
+
+# Unencrypted get from the namespace database file at the domain level.
+# This function retrieves a keyed item from a specific named database in the
+# domain directory.
+#
+# Parameters:
+#   $cmd             - Command request keyword (get).
+#   $tail            - Tail of the command.  This is a colon separated list
+#                      consisting of the domain and the 'namespace' 
+#                      which selects the gdbm file to do the lookup in,
+#                      & separated list of keys to lookup.  Note that
+#                      the values are returned as an & separated list too.
+#   $client          - File descriptor open on the client.
+# Returns:
+#   1       - Continue processing.
+#   0       - Exit.
+#  Side effects:
+#     reply is written to $client.
+#
+
+sub get_domain_handler {
+    my ($cmd, $tail, $client) = @_;
+
+    my $userinput = "$client:$tail";
+
+    my ($udom,$namespace,$what)=split(/:/,$tail,3);
+    chomp($what);
+    my @queries=split(/\&/,$what);
+    my $qresult='';
+    my $hashref = &tie_domain_hash($udom, "$namespace", &GDBM_READER());
+    if ($hashref) {
+        for (my $i=0;$i<=$#queries;$i++) {
+            $qresult.="$hashref->{$queries[$i]}&";
+        }
+        if (&untie_domain_hash($hashref)) {
+            $qresult=~s/\&$//;
+            &Reply($client, "$qresult\n", $userinput);
+        } else {
+            &Failure( $client, "error: ".($!+0)." untie(GDBM) Failed ".
+                      "while attempting getdom\n",$userinput);
+        }
+    } else {
+        &Failure($client, "error: ".($!+0)." tie(GDBM) Failed ".
+                 "while attempting getdom\n",$userinput);
+    }
+
+    return 1;
+}
+&register_handler("getdom", \&get_domain_handler, 0, 1, 0);
+
+
+#
 #  Puts an id to a domains id database. 
 #
 #  Parameters:
@@ -3872,15 +3958,23 @@ sub tmp_put_handler {
 
     my $userinput = "$cmd:$what";	# Reconstruct for logging.
 
-
-    my $store;
+    my ($record,$context) = split(/:/,$what);
+    if ($context ne '') {
+        chomp($context);
+        $context = &unescape($context);
+    }
+    my ($id,$store);
     $tmpsnum++;
-    my $id=$$.'_'.$clientip.'_'.$tmpsnum;
+    if ($context eq 'resetpw') {
+        $id = &md5_hex(&md5_hex(time.{}.rand().$$));
+    } else {
+        $id = $$.'_'.$clientip.'_'.$tmpsnum;
+    }
     $id=~s/\W/\_/g;
-    $what=~s/\n//g;
+    $record=~s/\n//g;
     my $execdir=$perlvar{'lonDaemons'};
     if ($store=IO::File->new(">$execdir/tmp/$id.tmp")) {
-	print $store $what;
+	print $store $record;
 	close $store;
 	&Reply($client, "$id\n", $userinput);
     } else {
@@ -4342,10 +4436,10 @@ sub get_institutional_code_format_handle
 						    \%cat_titles,
 						    \%cat_order);
     if ($formatreply eq 'ok') {
-	my $codes_str = &hash2str(%codes);
-	my $codetitles_str = &array2str(@codetitles);
-	my $cat_titles_str = &hash2str(%cat_titles);
-	my $cat_order_str = &hash2str(%cat_order);
+	my $codes_str = &Apache::lonnet::hash2str(%codes);
+	my $codetitles_str = &Apache::lonnet::array2str(@codetitles);
+	my $cat_titles_str = &Apache::lonnet::hash2str(%cat_titles);
+	my $cat_order_str = &Apache::lonnet::hash2str(%cat_order);
 	&Reply($client,
 	       $codes_str.':'.$codetitles_str.':'.$cat_titles_str.':'
 	       .$cat_order_str."\n",
@@ -4362,6 +4456,38 @@ sub get_institutional_code_format_handle
 &register_handler("autoinstcodeformat",
 		  \&get_institutional_code_format_handler,0,1,0);
 
+sub get_institutional_defaults_handler {
+    my ($cmd, $tail, $client)   = @_;
+    my $userinput               = "$cmd:$tail";
+
+    my $dom = $tail;
+    my %defaults_hash;
+    my @code_order;
+    my $outcome;
+    eval {
+        local($SIG{__DIE__})='DEFAULT';
+        $outcome = &localenroll::instcode_defaults($dom,\%defaults_hash,
+                                                   \@code_order);
+    };
+    if (!$@) {
+        if ($outcome eq 'ok') {
+            my $result='';
+            while (my ($key,$value) = each(%defaults_hash)) {
+                $result.=&escape($key).'='.&escape($value).'&';
+            }
+            $result .= 'code_order='.&escape(join('&',@code_order));
+            &Reply($client,$result."\n",$userinput);
+        } else {
+            &Reply($client,"error\n", $userinput);
+        }
+    } else {
+        &Failure($client,"unknown_cmd\n",$userinput);
+    }
+}
+&register_handler("autoinstcodedefaults",
+                  \&get_institutional_defaults_handler,0,1,0);
+
+
 # Get domain specific conditions for import of student photographs to a course
 #
 # Retrieves information from photo_permission subroutine in localenroll.
@@ -4489,6 +4615,31 @@ sub student_photo_handler {
 }
 &register_handler("studentphoto", \&student_photo_handler, 0, 1, 0);
 
+sub inst_usertypes_handler {
+    my ($cmd, $domain, $client) = @_;
+    my $res;
+    my $userinput = $cmd.":".$domain; # For logging purposes.
+    my (%typeshash,@order);  
+    if (&localenroll::inst_usertypes($domain,\%typeshash,\@order) eq 'ok') {
+        if (keys(%typeshash) > 0) {
+            foreach my $key (keys(%typeshash)) {
+                $res.=&escape($key).'='.&escape($typeshash{$key}).'&';
+            }
+        }
+        $res=~s/\&$//;
+        $res .= ':';
+        if (@order > 0) {
+            foreach my $item (@order) {
+                $res .= &escape($item).'&';
+            }
+        }
+        $res=~s/\&$//;
+    }
+    &Reply($client, "$res\n", $userinput);
+    return 1;
+}
+&register_handler("inst_usertypes", \&inst_usertypes_handler, 0, 1, 0);
+
 # mkpath makes all directories for a file, expects an absolute path with a
 # file or a trailing / if just a dir is passed
 # returns 1 on success 0 on failure
@@ -4863,67 +5014,6 @@ sub HUPSMAN {                      # sig
 }
 
 #
-#    Kill off hashes that describe the host table prior to re-reading it.
-#    Hashes affected are:
-#       %hostid, %hostdom %hostip %hostdns.
-#
-sub KillHostHashes {
-    foreach my $key (keys %hostid) {
-	delete $hostid{$key};
-    }
-    foreach my $key (keys %hostdom) {
-	delete $hostdom{$key};
-    }
-    foreach my $key (keys %hostip) {
-	delete $hostip{$key};
-    }
-    foreach my $key (keys %hostdns) {
-	delete $hostdns{$key};
-    }
-}
-#
-#   Read in the host table from file and distribute it into the various hashes:
-#
-#    - %hostid  -  Indexed by IP, the loncapa hostname.
-#    - %hostdom -  Indexed by  loncapa hostname, the domain.
-#    - %hostip  -  Indexed by hostid, the Ip address of the host.
-sub ReadHostTable {
-
-    open (CONFIG,"$perlvar{'lonTabDir'}/hosts.tab") || die "Can't read host file";
-    my $myloncapaname = $perlvar{'lonHostID'};
-    Debug("My loncapa name is : $myloncapaname");
-    my %name_to_ip;
-    while (my $configline=<CONFIG>) {
-	if ($configline !~ /^\s*\#/ && $configline !~ /^\s*$/ ) {
-	    my ($id,$domain,$role,$name)=split(/:/,$configline);
-	    $name=~s/\s//g;
-	    my $ip;
-	    if (!exists($name_to_ip{$name})) {
-		$ip = gethostbyname($name);
-		if (!$ip || length($ip) ne 4) {
-		    &logthis("Skipping host $id name $name no IP found\n");
-		    next;
-		}
-		$ip=inet_ntoa($ip);
-		$name_to_ip{$name} = $ip;
-	    } else {
-		$ip = $name_to_ip{$name};
-	    }
-	    $hostid{$ip}=$id;         # LonCAPA name of host by IP.
-	    $hostdom{$id}=$domain;    # LonCAPA domain name of host. 
-	    $hostname{$id}=$name;     # LonCAPA name -> DNS name
-	    $hostip{$id}=$ip;         # IP address of host.
-	    $hostdns{$name} = $id;    # LonCAPA name of host by DNS.
-
-	    if ($id eq $perlvar{'lonHostID'}) { 
-		Debug("Found me in the host table: $name");
-		$thisserver=$name; 
-	    }
-	}
-    }
-    close(CONFIG);
-}
-#
 #  Reload the Apache daemon's state.
 #  This is done by invoking /home/httpd/perl/apachereload
 #  a setuid perl script that can be root for us to do this job.
@@ -4954,13 +5044,12 @@ sub UpdateHosts {
     #  either dropped or changed hosts.  Note that the re-read of the table
     #  will take care of new and changed hosts as connections come into being.
 
+    #FIXME need a way to tell lonnet that it needs to reset host
+    #cached host info
 
-    KillHostHashes;
-    ReadHostTable;
-
-    foreach my $child (keys %children) {
+    foreach my $child (keys(%children)) {
 	my $childip = $children{$child};
-	if(!$hostid{$childip}) {
+	if (defined(&Apache::lonnet::get_hosts_from_ip($childip))) {
 	    logthis('<font color="blue"> UpdateHosts killing child '
 		    ." $child for ip $childip </font>");
 	    kill('INT', $child);
@@ -5120,63 +5209,6 @@ sub status {
     $0='lond: '.$what.' '.$local;
 }
 
-# ----------------------------------------------------------- Send USR1 to lonc
-
-sub reconlonc {
-    my $peerfile=shift;
-    &logthis("Trying to reconnect for $peerfile");
-    my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid";
-    if (my $fh=IO::File->new("$loncfile")) {
-	my $loncpid=<$fh>;
-        chomp($loncpid);
-        if (kill 0 => $loncpid) {
-	    &logthis("lonc at pid $loncpid responding, sending USR1");
-            kill USR1 => $loncpid;
-        } else {
-	    &logthis(
-              "<font color='red'>CRITICAL: "
-             ."lonc at pid $loncpid not responding, giving up</font>");
-        }
-    } else {
-      &logthis('<font color="red">CRITICAL: lonc not running, giving up</font>');
-    }
-}
-
-# -------------------------------------------------- Non-critical communication
-
-sub subreply {
-    my ($cmd,$server)=@_;
-    my $peerfile="$perlvar{'lonSockDir'}/".$hostname{$server};
-    my $sclient=IO::Socket::UNIX->new(Peer    =>"$peerfile",
-                                      Type    => SOCK_STREAM,
-                                      Timeout => 10)
-       or return "con_lost";
-    print $sclient "sethost:$server:$cmd\n";
-    my $answer=<$sclient>;
-    chomp($answer);
-    if (!$answer) { $answer="con_lost"; }
-    return $answer;
-}
-
-sub reply {
-  my ($cmd,$server)=@_;
-  my $answer;
-  if ($server ne $currenthostid) { 
-    $answer=subreply($cmd,$server);
-    if ($answer eq 'con_lost') {
-	$answer=subreply("ping",$server);
-        if ($answer ne $server) {
-	    &logthis("sub reply: answer != server answer is $answer, server is $server");
-           &reconlonc("$perlvar{'lonSockDir'}/".$hostname{$server});
-        }
-        $answer=subreply($cmd,$server);
-    }
-  } else {
-    $answer='self_reply';
-  } 
-  return $answer;
-}
-
 # -------------------------------------------------------------- Talk to lonsql
 
 sub sql_reply {
@@ -5245,8 +5277,7 @@ $SIG{USR1} = \&checkchildren;
 $SIG{USR2} = \&UpdateHosts;
 
 #  Read the host hashes:
-
-ReadHostTable;
+&Apache::lonnet::load_hosts_tab();
 
 my $dist=`$perlvar{'lonDaemons'}/distprobe`;
 
@@ -5325,7 +5356,8 @@ sub make_new_child {
 #        my $tmpsnum=0;            # Now global
 #---------------------------------------------------- kerberos 5 initialization
         &Authen::Krb5::init_context();
-	unless (($dist eq 'fedora4') || ($dist eq 'suse9.3')) {
+	unless (($dist eq 'fedora5') || ($dist eq 'fedora4') ||  
+		($dist eq 'fedora6') || ($dist eq 'suse9.3')) {
 	    &Authen::Krb5::init_ets();
 	}
 
@@ -5339,15 +5371,15 @@ sub make_new_child {
 	
 	my $outsideip=$clientip;
 	if ($clientip eq '127.0.0.1') {
-	    $outsideip=$hostip{$perlvar{'lonHostID'}};
+	    $outsideip=&Apache::lonnet::get_host_ip($perlvar{'lonHostID'});
 	}
 
-	my $clientrec=($hostid{$outsideip}     ne undef);
+	my $clientrec=defined(&Apache::lonnet::get_hosts_from_ip($outsideip));
 	my $ismanager=($managers{$outsideip}    ne undef);
 	$clientname  = "[unknonwn]";
 	if($clientrec) {	# Establish client type.
 	    $ConnectionType = "client";
-	    $clientname = $hostid{$outsideip};
+	    $clientname = (&Apache::lonnet::get_hosts_from_ip($outsideip))[-1];
 	    if($ismanager) {
 		$ConnectionType = "both";
 	    }
@@ -5454,14 +5486,9 @@ sub make_new_child {
  
 	if ($clientok) {
 # ---------------- New known client connecting, could mean machine online again
-	    
-	    foreach my $id (keys(%hostip)) {
-		if ($hostip{$id} ne $clientip ||
-		    $hostip{$currenthostid} eq $clientip) {
-		    # no need to try to do recon's to myself
-		    next;
-		}
-		&reconlonc("$perlvar{'lonSockDir'}/".$hostname{$id});
+	    if (&Apache::lonnet::get_host_ip($currenthostid) ne $clientip 
+		&& $clientip ne '127.0.0.1') {
+		&Apache::lonnet::reconlonc();
 	    }
 	    &logthis("<font color='green'>Established connection: $clientname</font>");
 	    &status('Will listen to '.$clientname);
@@ -5738,7 +5765,8 @@ sub validate_user {
 		my $krbservice = "krbtgt/".$contentpwd."\@".$contentpwd;
 		my $krbserver  = &Authen::Krb5::parse_name($krbservice);
 		my $credentials= &Authen::Krb5::cc_default();
-		$credentials->initialize($krbclient);
+		$credentials->initialize(&Authen::Krb5::parse_name($user.'@'
+                                                                 .$contentpwd));
 		my $krbreturn  = &Authen::Krb5::get_in_tkt_with_password($krbclient,
 									 $krbserver,
 									 $password,
@@ -5751,7 +5779,12 @@ sub validate_user {
 	    #  Authenticate via installation specific authentcation method:
 	    $validated = &localauth::localauth($user, 
 					       $password, 
-					       $contentpwd);
+					       $contentpwd,
+					       $domain);
+	    if ($validated < 0) {
+		&logthis("localauth for $contentpwd $user:$domain returned a $validated");
+		$validated = 0;
+	    }
 	} else {			# Unrecognized auth is also bad.
 	    $validated = 0;
 	}
@@ -5777,8 +5810,7 @@ sub addline {
     my ($fname,$hostid,$ip,$newline)=@_;
     my $contents;
     my $found=0;
-    my $expr='^'.$hostid.':'.$ip.':';
-    $expr =~ s/\./\\\./g;
+    my $expr='^'.quotemeta($hostid).':'.quotemeta($ip).':';
     my $sh;
     if ($sh=IO::File->new("$fname.subscription")) {
 	while (my $subline=<$sh>) {
@@ -6139,9 +6171,10 @@ sub sethost {
     }
 
     if (!defined($hostid)) { $hostid=$perlvar{'lonHostID'}; }
-    if ($hostip{$perlvar{'lonHostID'}} eq $hostip{$hostid}) {
+    if (&Apache::lonnet::get_host_ip($perlvar{'lonHostID'}) 
+	eq &Apache::lonnet::get_host_ip($hostid)) {
 	$currenthostid  =$hostid;
-	$currentdomainid=$hostdom{$hostid};
+	$currentdomainid=&Apache::lonnet::domain($hostid);
 	&logthis("Setting hostid to $hostid, and domain to $currentdomainid");
     } else {
 	&logthis("Requested host id $hostid not an alias of ".
@@ -6157,96 +6190,6 @@ sub version {
     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 ($mtime)=(stat($perlvar{'lonIDsDir'}.'/'.$filename))[9];
-	    if ($curtime-$mtime < 1800) { $numusers++; }
-	}
-	closedir(LONIDS);
-    }
-    my $userloadpercent=0;
-    my $maxuserload=$perlvar{'lonUserLoadLim'};
-    if ($maxuserload) {
-	$userloadpercent=100*$numusers/$maxuserload;
-    }
-    $userloadpercent=sprintf("%.2f",$userloadpercent);
-    return $userloadpercent;
-}
-
-# Routines for serializing arrays and hashes (copies from lonnet)
-
-sub array2str {
-  my (@array) = @_;
-  my $result=&arrayref2str(\@array);
-  $result=~s/^__ARRAY_REF__//;
-  $result=~s/__END_ARRAY_REF__$//;
-  return $result;
-}
-                                                                                 
-sub arrayref2str {
-  my ($arrayref) = @_;
-  my $result='__ARRAY_REF__';
-  foreach my $elem (@$arrayref) {
-    if(ref($elem) eq 'ARRAY') {
-      $result.=&arrayref2str($elem).'&';
-    } elsif(ref($elem) eq 'HASH') {
-      $result.=&hashref2str($elem).'&';
-    } elsif(ref($elem)) {
-      #print("Got a ref of ".(ref($elem))." skipping.");
-    } else {
-      $result.=&escape($elem).'&';
-    }
-  }
-  $result=~s/\&$//;
-  $result .= '__END_ARRAY_REF__';
-  return $result;
-}
-                                                                                 
-sub hash2str {
-  my (%hash) = @_;
-  my $result=&hashref2str(\%hash);
-  $result=~s/^__HASH_REF__//;
-  $result=~s/__END_HASH_REF__$//;
-  return $result;
-}
-                                                                                 
-sub hashref2str {
-  my ($hashref)=@_;
-  my $result='__HASH_REF__';
-  foreach (sort(keys(%$hashref))) {
-    if (ref($_) eq 'ARRAY') {
-      $result.=&arrayref2str($_).'=';
-    } elsif (ref($_) eq 'HASH') {
-      $result.=&hashref2str($_).'=';
-    } elsif (ref($_)) {
-      $result.='=';
-      #print("Got a ref of ".(ref($_))." skipping.");
-    } else {
-        if ($_) {$result.=&escape($_).'=';} else { last; }
-    }
-
-    if(ref($hashref->{$_}) eq 'ARRAY') {
-      $result.=&arrayref2str($hashref->{$_}).'&';
-    } elsif(ref($hashref->{$_}) eq 'HASH') {
-      $result.=&hashref2str($hashref->{$_}).'&';
-    } elsif(ref($hashref->{$_})) {
-       $result.='&';
-      #print("Got a ref of ".(ref($hashref->{$_}))." skipping.");
-    } else {
-      $result.=&escape($hashref->{$_}).'&';
-    }
-  }
-  $result=~s/\&$//;
-  $result .= '__END_HASH_REF__';
-  return $result;
-}
 
 # ----------------------------------- POD (plain old documentation, CPAN style)