From beacbef7dc7b8bef6c5309aeb4492d3546d463ee Mon Sep 17 00:00:00 2001
From: Fons Rademakers <Fons.Rademakers@cern.ch>
Date: Fri, 7 Nov 2003 03:29:42 +0000
Subject: [PATCH] From Gerri: Index: README/README.AUTH  o Update explaining
 tutorial use

Index: base/src/TFile.cxx
 o ::Open(): call TNetFile also if same host but different user
   (to access files protected by password)

Index: globusauth/src/GlobusAuth.cxx
 o Aestethic changes (shortening of a few lines)

Index: krb5auth/src/Krb5Auth.cxx
 o Simplify two debug printouts
 o Change debug print to stderr in Info(...; add gDebug control.

Index: net/inc/THostAuth.h
 o Modify default ctor
 o Add method HasMethod to test method availability

Index: net/src/TAuthenticate.cxx
 o make sure that if fgUser (and nothing else) is set, this is
   the default user name
 o Make sure that requiring roots/rootk uses correctly details
   found for those methods in .rootauthrc
 o Fix return of GetPromptUser()
 o Fix problem with wild cards
 o Add check for wildcard host names in method GetHostAuth
 o Remove debug printout in method ReadAuthRc

Index: net/src/THostAuth.cxx
 o Modify default ctor
 o Add method HaveMethod to test method availability
 o Aestethic changes (shortening of a few lines)

Index: net/src/TNetFile.cxx
 o Remove precompiler unused #if's in method ConnectServer

Index: proof/inc/TProofServ.h
 o Remove method ReadProofAuth, add method RecvHostAuth
   (To receive directly the authentication info in ProofServ
   instead of reading it from temporary files
   /usr/tmp/proofserv.<id>)

Index: proof/src/TProofServ.cxx
 o All mods needed to remove method ReadProofAuth and add
   method RecvHostAuth (see above).
   Modified methods: Setup, CollectAuthInfo .
 o Fix bug in CollectAuthInfo switching ReUse off by default
   for method UsrPwd
 o Removing automatic choice of UidGid for local slaves
 o Setting order of default UidGid authentication to last
 o Aestethic changes in CheckAuth

Index: proof/src/TSlave.cxx
 o transmit passwd for UsrPwd and SRP authentication also to slaves
 o All mods needed to send auth info to ProofServ instead of
   proofd (see above)

Index: proofd/src/proofd.cxx
 o Fix compiling problem with namespaces for Kerberos
 o Remove redundant 'access' calls
 o Authenticate: do not recive auth info (done in ProofServ)
 o ProofExec: send TmpDir to proofserv (for key location)
 o Define gSystemdaemonc as $ROOTETCDIR/system.rootdaemonrc

Index: rootd/src/rootd.cxx
 o Define gSystemdaemonc as $ROOTETCDIR/system.rootdaemonrc

Index: rpdutils/inc/rpdp.h
 o Rename gAuthAllow as gSystemDaemonRc
 o Rename kDaemonAccess as kDaemonRc

Index: rpdutils/src/rpdutils.cxx
 o Fix compiling problem with namespaces for Kerberos
 o Define kDaemonRc as .rootdaemonrc (it was daemon.access)
 o Add support for $HOME/.rootdaemonrc
 o Add support for daemon dependent access rules
 o Aestethic changes in CheckAuth (drop commented lines)

Index: srputils/src/SRPAuth.cxx
 o set static flags only when authentication is successful

Index: tutorials/TestAuth.C
 o Test using TFTP instead of TNetFile (faster and runs also
   with local host fqdn)
 o Add test for kerberos


git-svn-id: http://root.cern.ch/svn/root/trunk@7534 27541ba8-7e3a-0410-8455-c3a389f83636
---
 README/README.AUTH                         | 108 ++++-
 base/src/TFile.cxx                         |  10 +-
 etc/{daemon.access => system.rootdaemonrc} |  16 +-
 globusauth/src/GlobusAuth.cxx              |   4 +-
 io/src/TFile.cxx                           |  10 +-
 krb5auth/inc/Krb5Auth.h                    |   4 +-
 krb5auth/src/Krb5Auth.cxx                  |  25 +-
 net/inc/THostAuth.h                        |   8 +-
 net/src/TAuthenticate.cxx                  | 154 +++---
 net/src/THostAuth.cxx                      |  74 +--
 net/src/TNetFile.cxx                       |  16 +-
 proof/inc/TProofServ.h                     |   4 +-
 proof/src/TProofServ.cxx                   | 354 +++++++-------
 proof/src/TSlave.cxx                       |  45 +-
 proofd/src/proofd.cxx                      |  89 ++--
 rootd/src/rootd.cxx                        |  11 +-
 rpdutils/inc/rpdp.h                        |   9 +-
 rpdutils/src/net.cxx                       |   9 +-
 rpdutils/src/rpdutils.cxx                  |  65 ++-
 srputils/src/SRPAuth.cxx                   |  19 +-
 tutorials/TestAuth.C                       | 527 +++++++++++----------
 21 files changed, 845 insertions(+), 716 deletions(-)
 rename etc/{daemon.access => system.rootdaemonrc} (85%)

diff --git a/README/README.AUTH b/README/README.AUTH
index c1ed0f8a46b..825ca208a52 100644
--- a/README/README.AUTH
+++ b/README/README.AUTH
@@ -1,14 +1,12 @@
-
-
 Authentication to rootd/proofd servers
 ======================================
 
-The rootd/proofd daemon servers accept 6 methods of authentication, listed 
+The rootd/proofd daemon servers accept 6 methods of authentication, listed
 in Table 1, together with their internal codes and short names.
 Method 5 (rfio) is provided for fast access when security is not an issue.
-Method 0 is 'secured' by using a session public key, automatically 
+Method 0 is 'secured' by using a session public key, automatically
 generated, which allows to avoid direct exchange of passwords; since this
-may slow down the process, it can be switched of if not needed. 
+may slow down the process, it can be switched of if not needed.
 
    Table 1: authentication methods available
   +-------------------------------------------------------------------------+
@@ -28,6 +26,10 @@ $ROOTSYS/etc/system.rootrc), the file $HOME/.rootauthrc (superseded by the
 variable ROOTAUTHRC, if defined), or during the root session as explained
 below.
 
+A test macro TestAuth.C is provided under the tutorials directory. Its use
+is explained at the end of this file.
+
+
 Controlling access
 ==================
 
@@ -35,10 +37,11 @@ Upon request of access, rootd/proofd build a list of secure methods available
 locally; the list always comprises UsrPwd; SRP, Kerberos and Globus, are added
 if ROOT has been compiled with support for them; SSH is added if the 'sshd'
 daemon is running. By default the two daemons accept authentications only via
-the methods in such a list. The administrator of the daemons can, however, 
+the methods in such a list. The administrator of the daemons can, however,
 grant access via other authentication methods (or deny any access) by defining
-a host specific list in etc/daemon.access (see the example for this file 
-under etc for more details).
+a host specific list in etc/system.rootdaemonrc or $HOME/.rootdaemonrc
+(see the example for this file under etc for more details).
+
 
 Negotiation
 ===========
@@ -51,6 +54,7 @@ the server sends back the list of the remaining methods accepted (if any); the
 client compares the server list with its own list of remaining methods and
 makes a new attempt if the overlap of the two lists is not empty; and so on.
 
+
 Slave/Data servers authentication during a PROOF session
 ========================================================
 
@@ -58,8 +62,8 @@ During a PROOF session there is the potential problem of Master/Slave or
 Slave/Data_Server authentication. For slaves, the list of methods to be tried
 is specified in the proof.conf file as a list of methods short names. However,
 before build the corresponding entry in THostAuth (see below) TProofServ checks
-that the method can be applied, i.e. that there exist valid credentials. 
-The way the latters are transmitted depends on the method and on the 
+that the method can be applied, i.e. that there exist valid credentials.
+The way the latters are transmitted depends on the method and on the
 Client/Master authentication method.
 
  * UsrPwd: to authenticate 'usrpwd' to slaves, the master needs the relevant
@@ -72,7 +76,7 @@ Client/Master authentication method.
            in the .netrc or .rootnetrc files; the syntax is the same as for
            'clear' authentication with the keyword 'secure' at the place of
            'machine'. However, if the client/master authentication was also
-           'SRP', the master can receive the password from the client; the 
+           'SRP', the master can receive the password from the client; the
            password is sent encrypted with the internal RSA key generated for
            the session. To use this option, set 'Proofd.SendSRPPwd 1' in your
            .rootrc (default is 0).
@@ -91,7 +95,7 @@ Client/Master authentication method.
  * UidGid  to authenticate 'uidgid' to slaves, the user must have the same
            (uid,gid) on master and slaves.
 
-Negotiation is active also between master and slaves, so may be a good habit 
+Negotiation is active also between master and slaves, so may be a good habit
 to ask for 'uidgid' first to accelerate as possible the authentication process.
 
 The method actually used is listed by gProof->Print().
@@ -144,12 +148,12 @@ directives are the following:
 
 * The <method>.ReUse directives specify whether root reuse valid authentication
   once established; possible values are '0' or 'no' for OFF, '1' or 'yes' for ON.
-  When this option is active, the client generates a session RSA key pair and 
-  transmits the public key to the server; the server generates a session 'token' 
-  which can be used by the client for later access to the server. 
-  This facility is implemented for all methods except UidGid (for which there would 
+  When this option is active, the client generates a session RSA key pair and
+  transmits the public key to the server; the server generates a session 'token'
+  which can be used by the client for later access to the server.
+  This facility is implemented for all methods except UidGid (for which there would
   be no advantage); it is switched ON by default for UsrPwd, SRP, Globus and SSH,
-  since it allows to speed up repeated access to the same server.  
+  since it allows to speed up repeated access to the same server.
   For Krb5 it is implemented but switched OFF by default, since it does not improve
   on authentication time.
 
@@ -159,7 +163,7 @@ directives are the following:
   Globus.ReUse:  yes
   SSH.ReUse:     1
 
-  NB: unless 'UsrPwd.Crypt 0' (see below), for UsrPwd the password is always sent 
+  NB: unless 'UsrPwd.Crypt 0' (see below), for UsrPwd the password is always sent
       encrypted with the session RSA key, even if UsrPwd.ReUse is OFF.
 
 * Other directives
@@ -375,7 +379,6 @@ classes:
    methods are the ones listed in meths[nmet].
 
 
-
 TAuthDetails
 ============
 
@@ -385,7 +388,74 @@ during the same session. Each THostAuth contains a list of TAuthDetails objects
 pertaining to {host,user)
 
 
+TestAuth.C
+==========
+
+This macro is provided to test the authentication methods available.
+The macro is located under $ROOTSYS/tutorials.
+Before executing it, start a rootd daemon on a separate window
+
+  rootd -d 3 -f
+
+The "-d 3" option allows to get some debugging info, useful in the
+case something goes wrong.
+
+Then run
+
+  root -q -l $ROOTSYS/tutorials/TestAuth.C
+
+and answer to the requests for passwords or similar to initialize
+credentials. Upon success, you should get at the end something like this
+
+
+   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   +                                                                             +
+   +   Result of the tests:                                                      +
+   +                                                                             +
+   +   Method: 0 (UsrPwd): successful! (reuse: successful!)                      +
+   +   Method: 1    (SRP): successful! (reuse: successful!)                      +
+   +   Method: 2   (Krb5): successful! (reuse: successful!)                      +
+   +   Method: 3 (Globus): successful! (reuse: successful!)                      +
+   +   Method: 4    (SSH): successful! (reuse: successful!)                      +
+   +   Method: 5 (UidGid): successful!                                           +
+   +                                                                             +
+   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+The macro assumes rootd accepting connections on port 1094; if this
+is not the case you can pass the port number as the first argument to
+the macro.
+
+The macro assumes hat you are trying to login as yourself to rootd,
+ie with the username your are logged in. You may change this passing
+a different username "newuser" as second argument. In this case you
+have to start rootd from the "newuser" account or as supersuser,
+to be avoid access problems. Also, for SSH, make sure that "newuser"
+can execute $ROOTSYS/bin/ssh2rpd.
+
+The macro assumes that the kerberos principal is in the form
+
+     <current_user>@<DEFAULT_REALM>
+
+where <DEFAULT_REALM> is searched for in the Kerberos conf file
+/etc/krb5.conf (or $KRB5_CONFIG). If the principal for the current
+user is different, you have to pass it as third argument to TestAuth.C.
 
+Finally, for Globus, if the certicate files and directories are not
+standard, you should pass the ones to be used as fourth argument, the
+syntax being the same as for $HOME/.rootauthrc .
 
+This is a summary of the arguments to TestAuth.C:
 
+   TestAuth.C(<port>,"<user>","<krb5_princ","<globus_det>")
 
+   <port>          = rootd port (default 1094)
+   <user>          = login user name for the test
+                    (default from getpwuid)
+   <krb5_princ>    = Principal to be used for Krb5 authentication
+                     in the form user@THE.REA.LM
+                     ( default: <running_user@Default_Realm with
+                                Default_realm taken from /etc/krb5.conf
+                                or the $KRB5_CONFIG file )
+   <globus_det>    = details for the globus authentication
+                     ( default: ad:certificates cd:$HOME/.globus
+                                cf:usercert.pem kf:userkey.pem )
diff --git a/base/src/TFile.cxx b/base/src/TFile.cxx
index 8bf55bd381e..fa1da2b5096 100644
--- a/base/src/TFile.cxx
+++ b/base/src/TFile.cxx
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name:  $:$Id: TFile.cxx,v 1.101 2003/09/21 21:38:31 rdm Exp $
+// @(#)root/base:$Name:  $:$Id: TFile.cxx,v 1.102 2003/09/27 18:45:45 rdm Exp $
 // Author: Rene Brun   28/11/94
 
 /*************************************************************************
@@ -1927,10 +1927,16 @@ TFile *TFile::Open(const char *name, Option_t *option, const char *ftitle,
 
    if (!strncmp(name, "root:", 5) || !strncmp(name, "roots:", 6) ||
        !strncmp(name, "rootk:", 6)) {
+      // if the url points to the local user on the localhost
+      // do not operate network machinery
+      Bool_t sameUser = kFALSE;
       TUrl url(name);
+      UserGroup_t *u = gSystem->GetUserInfo();
+      if (u && !strcmp(u->fUser, url.GetUser())) sameUser = kTRUE;
+      delete u;
       TInetAddress a(gSystem->GetHostByName(url.GetHost()));
       TInetAddress b(gSystem->GetHostByName(gSystem->HostName()));
-      if (strcmp(a.GetHostName(), b.GetHostName())) {
+      if (strcmp(a.GetHostName(), b.GetHostName()) || !sameUser) {
          if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
              h->LoadPlugin() == 0)
             f = (TFile*) h->ExecPlugin(5, name, option, ftitle, compress, netopt);
diff --git a/etc/daemon.access b/etc/system.rootdaemonrc
similarity index 85%
rename from etc/daemon.access
rename to etc/system.rootdaemonrc
index ffa8c6101ba..4ae3f9cdd0c 100644
--- a/etc/daemon.access
+++ b/etc/system.rootdaemonrc
@@ -1,8 +1,12 @@
 #
-#  daemon.access   This file describes the names of the hosts for which
-#                  the allowed authentication methods are not the default ones
-#                  as specified in system.rootc (if any).
-#                  This file is used by the 'rootd' and 'proofd' daemons.
+#  $ROOTSYS/etc/system.rootdaemonrc, $HOME/.rootdaemonrc 
+#      This files describe the names of the hosts for which
+#      the allowed authentication methods are not the default ones
+#      as specified in system.rootc (if any).
+#      This file is used by the 'rootd' and 'proofd' daemons.
+#
+#      If existing, $HOME/.rootdaemonrc has priority over 
+#      $ROOTSYS/etc/system.rootdaemonrc 
 #
 #  Format:
 #    - lines starting with '#' are comment lines.
@@ -10,6 +14,9 @@
 #    - hosts can specified either with their FQDN (eg, pcepsft43.cern.ch) or
 #      their IP address (eg 137.138.99.73).
 #
+#    - host names can be followed by :rootd or :proofd to define directives
+#      applying only to the given service
+#
 #    - the '*' character can be used in the first field of the name to 
 #      indicate a set of machines, e.g. pcepsft*.cern.ch applies to all 
 #      'pcepsft' machines in the domain 'cern.ch'
@@ -76,6 +83,7 @@
 # lxplus*.cern.ch      4 1 globus 0:ganis:gganis 5  
 # pcepsft43.cern.ch    4 3 1 5 2 0
 # afal57.cern.ch       0 5 4 
+# pcep*.cern.ch:rootd  4 1 3 2 5 0
 #
 # Everything allowed from the local host (for testing)
 #
diff --git a/globusauth/src/GlobusAuth.cxx b/globusauth/src/GlobusAuth.cxx
index 05319535e3b..f024a41e1c4 100644
--- a/globusauth/src/GlobusAuth.cxx
+++ b/globusauth/src/GlobusAuth.cxx
@@ -1,4 +1,4 @@
-// @(#)root/globus:$Name:  $:$Id: GlobusAuth.cxx,v 1.4 2003/10/07 21:09:55 rdm Exp $
+// @(#)root/globus:$Name:  $:$Id: GlobusAuth.cxx,v 1.5 2003/10/22 18:48:36 rdm Exp $
 // Author: Gerardo Ganis  15/01/2003
 
 /*************************************************************************
@@ -111,7 +111,7 @@ Int_t GlobusAuthenticate(TAuthenticate * Auth, TString & user,
    protocol = Auth->GetProtocol();
 
    if (gDebug > 2)
-      Info("GlobusAuthenticate", " enter: %s %s", protocol.Data(),
+      Info("GlobusAuthenticate", " enter: protocol:'%s' user:'%s'", protocol.Data(),
            user.Data());
 
    // If we are called for local cleanup, do it and return ...
diff --git a/io/src/TFile.cxx b/io/src/TFile.cxx
index 8bf55bd381e..fa1da2b5096 100644
--- a/io/src/TFile.cxx
+++ b/io/src/TFile.cxx
@@ -1,4 +1,4 @@
-// @(#)root/base:$Name:  $:$Id: TFile.cxx,v 1.101 2003/09/21 21:38:31 rdm Exp $
+// @(#)root/base:$Name:  $:$Id: TFile.cxx,v 1.102 2003/09/27 18:45:45 rdm Exp $
 // Author: Rene Brun   28/11/94
 
 /*************************************************************************
@@ -1927,10 +1927,16 @@ TFile *TFile::Open(const char *name, Option_t *option, const char *ftitle,
 
    if (!strncmp(name, "root:", 5) || !strncmp(name, "roots:", 6) ||
        !strncmp(name, "rootk:", 6)) {
+      // if the url points to the local user on the localhost
+      // do not operate network machinery
+      Bool_t sameUser = kFALSE;
       TUrl url(name);
+      UserGroup_t *u = gSystem->GetUserInfo();
+      if (u && !strcmp(u->fUser, url.GetUser())) sameUser = kTRUE;
+      delete u;
       TInetAddress a(gSystem->GetHostByName(url.GetHost()));
       TInetAddress b(gSystem->GetHostByName(gSystem->HostName()));
-      if (strcmp(a.GetHostName(), b.GetHostName())) {
+      if (strcmp(a.GetHostName(), b.GetHostName()) || !sameUser) {
          if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
              h->LoadPlugin() == 0)
             f = (TFile*) h->ExecPlugin(5, name, option, ftitle, compress, netopt);
diff --git a/krb5auth/inc/Krb5Auth.h b/krb5auth/inc/Krb5Auth.h
index b6ebdf04bd8..d2813f8e003 100644
--- a/krb5auth/inc/Krb5Auth.h
+++ b/krb5auth/inc/Krb5Auth.h
@@ -1,4 +1,4 @@
-// @(#)root/krb5auth:$Name:  $:$Id: Krb5Auth.h,v 1.2 2003/09/29 18:46:14 brun Exp $
+// @(#)root/krb5auth:$Name:  $:$Id: Krb5Auth.h,v 1.3 2003/10/28 23:29:24 brun Exp $
 // Author: Johannes Muelmenstaedt  17/03/2002
 
 /*************************************************************************
@@ -45,7 +45,7 @@ extern "C" {
       #include <com_err.h>
    #endif
    #include <krb5.h>
-   #if defined(linux)&&!defined(__COM_ERR_H)
+   #if defined(linux) && !defined(__COM_ERR_H)
       #include <com_err.h>
    #endif
    int krb5_net_read(krb5_context, int, char *, int); // ow ow ow!
diff --git a/krb5auth/src/Krb5Auth.cxx b/krb5auth/src/Krb5Auth.cxx
index 056e1f5be2e..231d9ad5318 100644
--- a/krb5auth/src/Krb5Auth.cxx
+++ b/krb5auth/src/Krb5Auth.cxx
@@ -1,4 +1,4 @@
-// @(#)root/krb5auth:$Name:  $:$Id: Krb5Auth.cxx,v 1.11 2003/10/22 18:48:36 rdm Exp $
+// @(#)root/krb5auth:$Name:  $:$Id: Krb5Auth.cxx,v 1.12 2003/10/27 09:48:35 rdm Exp $
 // Author: Johannes Muelmenstaedt  17/03/2002
 
 /*************************************************************************
@@ -213,11 +213,11 @@ Int_t Krb5Authenticate(TAuthenticate *auth, TString &user, TString &det, Int_t v
    strcpy(User,client->data->data);
 
    if (gDebug > 3) {
-      char *Realm = StrDup(client->realm.data);
-      int k = 0, len = strlen(client->realm.data);
-      for (k = 0; k < len; k++ ) { if ((int)Realm[k] == 32) Realm[k] = '\0'; }
+      char *Realm = new char[client->realm.length+1];
+      strncpy(Realm,client->realm.data,client->realm.length);
+      Realm[client->realm.length]= '\0';
       Info("Krb5Authenticate", "cc_get_principal: client: %s %s (%d %d)",
-           client->data->data,Realm, strlen(client->data->data), strlen(Realm));
+           client->data->data,Realm, client->data->length, client->realm.length);
       delete [] Realm;
    }
 
@@ -319,11 +319,11 @@ Int_t Krb5Authenticate(TAuthenticate *auth, TString &user, TString &det, Int_t v
    cleanup.server = server;
 
    if (gDebug > 3) {
-      char *Realm = StrDup(server->realm.data);
-      int k = 0, len = strlen(server->realm.data);
-      for (k = 0; k < len; k++) { if ((int)Realm[k] == 32) Realm[k] = '\0'; }
+      char *Realm = new char[server->realm.length+1];
+      strncpy(Realm,server->realm.data,server->realm.length);
+      Realm[server->realm.length]= '\0';
       Info("Krb5Authenticate","sname_to_principal: server: %s %s (%d %d)",
-           server->data->data, Realm, strlen(server->data->data), strlen(Realm));
+           server->data->data, Realm, server->data->length, server->realm.length);
       delete [] Realm;
    }
 
@@ -381,8 +381,9 @@ Int_t Krb5Authenticate(TAuthenticate *auth, TString &user, TString &det, Int_t v
 
       // Send the targetUser name
 
-   fprintf(stderr,"client is %s target is %s\n",
-           User,targetUser.Data());
+     if (gDebug > 0)
+        Info("Krb5Authenticate","client is %s target is %s",
+                                User,targetUser.Data());
       sock->Send(targetUser.Data(),kROOTD_KRB5);
 
       krb5_data outdata;
@@ -523,7 +524,7 @@ void Krb5InitCred(char *ClientPrincipal)
       if (Krb5Init!=0) delete[] Krb5Init;
       Krb5Init = "/usr/kerberos/bin/kinit";
   }
-  sprintf(cmd, "%s %s",Krb5Init,ClientPrincipal);
+  sprintf(cmd, "%s -f %s",Krb5Init,ClientPrincipal);
 
   if (gDebug > 2) Info("Krb5InitCred","executing: %s",cmd);
   gSystem->Exec(cmd);
diff --git a/net/inc/THostAuth.h b/net/inc/THostAuth.h
index a7730f4d565..48f3ca87907 100644
--- a/net/inc/THostAuth.h
+++ b/net/inc/THostAuth.h
@@ -1,4 +1,4 @@
-// @(#)root/net:$Name:  $:$Id: THostAuth.h,v 1.1 2003/08/29 10:38:19 rdm Exp $
+// @(#)root/net:$Name:  $:$Id: THostAuth.h,v 1.2 2003/08/29 17:23:31 rdm Exp $
 // Author: G. Ganis   19/03/2003
 
 /*************************************************************************
@@ -47,15 +47,15 @@ private:
 
 public:
 
-   THostAuth();
-   THostAuth(const char *host, const char *user, Int_t nmeth, Int_t *authmeth,
-             char **details);
+   THostAuth(const char *host = "localhost", const char *user = "",
+             Int_t nmeth = 0, Int_t *authmeth = 0, char **details = 0);
    THostAuth(const char *host, const char *user, Int_t authmeth,
              const char *details);
    virtual ~THostAuth();
 
    Int_t    NumMethods() const { return fNumMethods; }
    Int_t    GetMethods(Int_t meth) const { return fMethods[meth]; }
+   Bool_t   HasMethod(Int_t level);
    void     AddMethod(Int_t level, const char *details);
    void     RemoveMethod(Int_t level);
    void     ReOrder(Int_t nmet, Int_t *fmet);
diff --git a/net/src/TAuthenticate.cxx b/net/src/TAuthenticate.cxx
index dbafa963281..2646188a594 100644
--- a/net/src/TAuthenticate.cxx
+++ b/net/src/TAuthenticate.cxx
@@ -1,4 +1,4 @@
-// @(#)root/net:$Name:  $:$Id: TAuthenticate.cxx,v 1.25 2003/10/22 18:48:36 rdm Exp $
+// @(#)root/net:$Name:  $:$Id: TAuthenticate.cxx,v 1.26 2003/10/27 09:48:35 rdm Exp $
 // Author: Fons Rademakers   26/11/2000
 
 /*************************************************************************
@@ -125,8 +125,16 @@ TAuthenticate::TAuthenticate(TSocket *sock, const char *remote,
    }
 
    // Check or get user name
+   fUser = "";
+   TString CheckUser;
    if (user && strlen(user) > 0) {
       fUser = user;
+      CheckUser = user;
+   } else {
+      UserGroup_t *u = gSystem->GetUserInfo();
+      if (u)
+         CheckUser = u->fUser;
+      delete u;
    }
    fPasswd = "";
    fPwHash = kFALSE;
@@ -152,7 +160,7 @@ TAuthenticate::TAuthenticate(TSocket *sock, const char *remote,
            GetAuthInfo()->GetSize());
 
    // Check list of auth info for already loaded info about this host
-   fHostAuth = GetHostAuth(fqdn,fUser);
+   fHostAuth = GetHostAuth(fqdn, CheckUser);
 
    // If we did not find a good THostAuth instantiation, create one
    if (fHostAuth == 0) {
@@ -198,6 +206,23 @@ TAuthenticate::TAuthenticate(TSocket *sock, const char *remote,
       if (usr[0]) delete[] usr[0];
    }
 
+   // If a secific method has been requested via the protocol
+   // set it as first
+   Int_t Sec = -1;
+   if (fProtocol.Contains("roots") || fProtocol.Contains("proofs")) {
+      Sec = TAuthenticate::kSRP;
+   } else if (fProtocol.Contains("rootk") || fProtocol.Contains("proofk")) {
+      Sec = TAuthenticate::kKrb5;
+   }
+   if (Sec > -1 && Sec < kMAXSEC) {
+      if (fHostAuth->HasMethod(Sec)) {
+         fHostAuth->SetFirst(Sec);
+      } else {
+         TString Det(GetDefaultDetails(Sec, 1, CheckUser));
+         fHostAuth->SetFirst(Sec, Det);
+      }
+   }
+
    // This is what we have in memory
    if (gDebug > 3) {
       TIter next(fHostAuth->Established());
@@ -268,6 +293,8 @@ Bool_t TAuthenticate::Authenticate()
          if (GetUserPasswd(user, passwd, pwhash, (Bool_t &)kFALSE))
             return kFALSE;
       }
+      fUser = user;
+      fPasswd = passwd;
 
       if (fUser != "root")
          st = ClearAuth(user, passwd, pwhash);
@@ -284,6 +311,8 @@ Bool_t TAuthenticate::Authenticate()
          if (GetUserPasswd(user, passwd, pwhash, (Bool_t &)kTRUE))
             return kFALSE;
       }
+      fUser = user;
+      fPasswd = passwd;
 
       if (!fgSecAuthHook) {
          char *p;
@@ -301,6 +330,11 @@ Bool_t TAuthenticate::Authenticate()
                "no support for SRP authentication available");
          return kFALSE;
       }
+      // Fill present user info ...
+      if (st == 1) {
+         fPwHash = kFALSE;
+         fSRPPwd = kTRUE;
+      }
 
    } else if (fSecurity == kKrb5) {
 
@@ -675,10 +709,14 @@ void TAuthenticate::SetEnvironment()
       if (strlen(UsDef) > 0) {
          fgDefaultUser = UsDef;
       } else {
-         UserGroup_t *u = gSystem->GetUserInfo();
-         if (u)
-            fgDefaultUser = u->fUser;
-         delete u;
+         if (fgUser != "") {
+            fgDefaultUser = fgUser;
+         } else {
+            UserGroup_t *u = gSystem->GetUserInfo();
+            if (u)
+               fgDefaultUser = u->fUser;
+            delete u;
+         }
       }
 
       if (gDebug > 2)
@@ -745,11 +783,6 @@ Bool_t TAuthenticate::GetUserPasswd(TString & user, TString & passwd,
          return 1;
       }
    }
-   // Fill present user info ...
-   fUser = user;
-   fPasswd = passwd;
-   fPwHash = pwhash;
-   fSRPPwd = srppwd;
 
    return 0;
 }
@@ -947,7 +980,7 @@ Bool_t TAuthenticate::GetPromptUser()
 {
    // Static method returning the prompt user settings.
 
-   return fgDefaultUser;
+   return fgPromptUser;
 }
 
 //______________________________________________________________________________
@@ -1462,7 +1495,7 @@ Int_t TAuthenticate::GetAuthMeth(const char *Host, const char *Proto,
    // Space for AuthMeth and Details must be allocated outside
    // Default method is SSH.
 
-   int i;
+   Int_t i;
 
    if (gDebug > 2)
       ::Info("GetAuthMeth", "enter: h:%s p:%s u:%s (0x%lx 0x%lx) ",
@@ -1471,66 +1504,6 @@ Int_t TAuthenticate::GetAuthMeth(const char *Host, const char *Proto,
    if (*User[0] == 0)
       *User[0] = StrDup("");
 
-#if 0
-   // If 'host' is ourselves, then use rfio (to setup things correctly)
-   // Check and save the host FQDN ...
-   static TString LocalFQDN;
-   if (!gEnv->GetValue("Test.Auth",0)) {
-      if (LocalFQDN == "") {
-         TInetAddress addr = gSystem->GetHostByName(gSystem->HostName());
-         if (addr.IsValid()) {
-            LocalFQDN = addr.GetHostName();
-            if (LocalFQDN == "UnNamedHost")
-               LocalFQDN = addr.GetHostAddress();
-         }
-      }
-
-
-      Bool_t SameUser = kFALSE;
-      UserGroup_t *u = gSystem->GetUserInfo();
-      if (u)
-         if (!strcmp(u->fUser,*User[0])) SameUser = kTRUE;
-      delete u;
-
-      if (LocalFQDN == Host && SameUser) {
-         if (gDebug > 3)
-            ::Info("GetAuthMeth", "remote host is the local one (%s)",
-                   LocalFQDN.Data());
-         *NumMeth = new int[1];
-         *NumMeth[0] = 1;
-         AuthMeth[0] = new int[1];
-         AuthMeth[0][0] = 5;
-         Details[0] = new char *[1];
-         Details[0][0] = StrDup(Form("pt:0 ru:0 us:%s", *User[0]));
-         return 1;
-      }
-   }
-#endif
-
-   // If specific protocol was specified then it has absolute priority ...
-   if (!strcmp(Proto, "roots") || !strcmp(Proto, "proofs")) {
-      *NumMeth = new int[1];
-      *NumMeth[0] = 1;
-      AuthMeth[0] = new int[1];
-      AuthMeth[0][0] = 1;
-      Details[0] = new char *[1];
-      Details[0][0] = StrDup(Form("pt:%s ru:%s us:%s",
-                                  gEnv->GetValue("SRP.LoginPrompt", "no"),
-                                  gEnv->GetValue("SRP.ReUse", "0"),
-                                  gEnv->GetValue("SRP.Login", *User[0])));
-      return 1;
-   } else if (!strcmp(Proto, "rootk") || !strcmp(Proto, "proofk")) {
-      *NumMeth = new int[1];
-      *NumMeth[0] = 1;
-      AuthMeth[0] = new int[1];
-      AuthMeth[0][0] = 2;
-      Details[0] = new char *[1];
-      Details[0][0] = StrDup(Form("pt:%s ru:%s us:%s",
-                                  gEnv->GetValue("Krb5.LoginPrompt", "no"),
-                                  gEnv->GetValue("Krb5.ReUse", "0"),
-                                  gEnv->GetValue("Krb5.Login", *User[0])));
-      return 1;
-   }
    // Check then .rootauthrc (if there)
    char temp[kMAXPATHLEN];
    Int_t *am[kMAXSEC], *nh, nu = 0, j = 0;
@@ -1694,6 +1667,8 @@ Int_t TAuthenticate::CheckRootAuthrc(const char *Host, char ***user,
          // Skip comment lines
          if (line[0] == '#')
             continue;
+         if (!strncmp(line,"proofserv",9))
+            continue;
          char *pstr = 0;
          char *pdef = strstr(line, "default");
          sscanf(line,"%s %s",host,info);
@@ -2123,7 +2098,7 @@ Bool_t TAuthenticate::CheckHost(const char *Host, const char *host)
          }
       }
       nn++;
-   }
+    }
 
    // Act accordingly ...
    if (name == 0) {
@@ -2150,6 +2125,17 @@ Bool_t TAuthenticate::CheckHost(const char *Host, const char *host)
                   goto exit;
                }
             }
+         } else {
+#if 0
+            const char *sp = strstr(Host, host);
+            if (sp == 0 || sp != Host) {
+               retval = kFALSE;
+               goto exit;
+            }
+#else
+            retval = kFALSE;
+            goto exit;
+#endif
          }
       } else {
          if (!CheckHostWild(Host, host)) {
@@ -2491,6 +2477,8 @@ Int_t TAuthenticate::ClearAuth(TString & User, TString & Passwd, Bool_t & PwHash
          fPasswd = PasHash;
          fgPwHash = kTRUE;
          fPwHash = kTRUE;
+         fSRPPwd = kFALSE;
+         fgSRPPwd = kFALSE;
 
          fSocket->Send("\0", kROOTD_PASS);  // Needs this for consistency
          if (SecureSend(fSocket, 1, PasHash) == -1) {
@@ -2504,6 +2492,8 @@ Int_t TAuthenticate::ClearAuth(TString & User, TString & Passwd, Bool_t & PwHash
          fPasswd = Passwd;
          fgPwHash = kFALSE;
          fPwHash = kFALSE;
+         fSRPPwd = kFALSE;
+         fgSRPPwd = kFALSE;
 
          // Standard technique: invert passwd
          if (Passwd != "") {
@@ -3010,14 +3000,28 @@ THostAuth *TAuthenticate::GetHostAuth(const char *host, const char *user)
    // Check list of auth info for already loaded info about this host
    TIter next(GetAuthInfo());
    THostAuth *ai;
+   Bool_t NotFound = kTRUE;
    while ((ai = (THostAuth *) next())) {
       if (gDebug > 3)
          ai->Print("Authenticate:GetHostAuth");
 
       // Use default entry if existing and nothing more specific is found
-      if (!strcmp(ai->GetHost(),"default"))
+      if (!strcmp(ai->GetHost(),"default") && NotFound)
          rHA = ai;
 
+      // Check
+      if (ulen > 0) {
+         if (CheckHost(lHost,ai->GetHost()) && !strcmp(user, ai->GetUser())) {
+            rHA = ai;
+            NotFound = kFALSE;
+         }
+      } else {
+         if (CheckHost(lHost,ai->GetHost())) {
+            rHA = ai;
+            NotFound = kFALSE;
+         }
+      }
+
       if (ulen > 0) {
          if (lHost == ai->GetHost() && !strcmp(user, ai->GetUser())) {
             rHA = ai;
diff --git a/net/src/THostAuth.cxx b/net/src/THostAuth.cxx
index 947af11c283..6adf0db9550 100644
--- a/net/src/THostAuth.cxx
+++ b/net/src/THostAuth.cxx
@@ -1,4 +1,4 @@
-// @(#)root/net:$Name:  $:$Id: THostAuth.cxx,v 1.3 2003/09/07 18:25:46 rdm Exp $
+// @(#)root/net:$Name:  $:$Id: THostAuth.cxx,v 1.4 2003/10/07 14:03:03 rdm Exp $
 // Author: G. Ganis   19/03/2003
 
 /*************************************************************************
@@ -30,22 +30,9 @@
 
 ClassImp(THostAuth)
 
-//______________________________________________________________________________
-THostAuth::THostAuth(): TObject()
-{
-   // Default constructor
-
-   fHost        = "";
-   fUser        = "";
-   fNumMethods  = 0;
-   fMethods     = 0;
-   fDetails     = 0;
-   fEstablished = 0;
-}
-
 //______________________________________________________________________________
 THostAuth::THostAuth(const char *host, const char *user, Int_t nmeth,
-                     Int_t *authmeth, char **details)
+                     Int_t *authmeth, char **details) : TObject()
 {
    // Create hostauth object.
 
@@ -73,14 +60,23 @@ THostAuth::THostAuth(const char *host, const char *user, Int_t nmeth,
    }
 
    fNumMethods = nmeth;
-   fMethods    = new Int_t[nmeth];
-   if (authmeth != 0) {
-      for (i = 0; i < nmeth; i++) { fMethods[i] = authmeth[i]; }
+   if (fNumMethods > 0) {
+      if (authmeth != 0) {
+         fMethods    = new Int_t[fNumMethods];
+         for (i = 0; i < nmeth; i++) {
+            fMethods[i] = authmeth[i];
+         }
+      } else {
+         fNumMethods = 0;
+      }
    }
-   fDetails = new TString[nmeth];
-   if (details) {
-      for (i = 0; i < nmeth; i++) {
-         if (details[i]) fDetails[i] = details[i];
+
+   if (fNumMethods > 0) {
+      fDetails = new TString[nmeth];
+      if (details) {
+         for (i = 0; i < nmeth; i++) {
+            if (details[i]) fDetails[i] = details[i];
+         }
       }
    }
    fEstablished = new TList;
@@ -88,7 +84,7 @@ THostAuth::THostAuth(const char *host, const char *user, Int_t nmeth,
 
 //______________________________________________________________________________
 THostAuth::THostAuth(const char *host, const char *user, Int_t authmeth,
-                     const char *details)
+                     const char *details) : TObject()
 {
    // Create hostauth object with one method only.
 
@@ -216,7 +212,9 @@ const char *THostAuth::GetDetails(Int_t level)
    int i;
    for (i = 0; i < fNumMethods; i++) {
       if (fMethods[i] == level) {
-         if (gDebug > 3) Info("GetDetails"," %d: returning fDetails[%d]: %s", level,i,fDetails[i].Data());
+         if (gDebug > 3)
+            Info("GetDetails"," %d: returning fDetails[%d]: %s",
+                 level,i,fDetails[i].Data());
          return fDetails[i];
       }
    }
@@ -224,6 +222,20 @@ const char *THostAuth::GetDetails(Int_t level)
    return empty;
 }
 
+//______________________________________________________________________________
+Bool_t THostAuth::HasMethod(Int_t level)
+{
+   // Return kTRUE if method 'level' is in the list
+
+   int i;
+   for (i = 0; i < fNumMethods; i++) {
+      if (fMethods[i] == level) {
+         return kTRUE;
+      }
+   }
+   return kFALSE;
+}
+
 //______________________________________________________________________________
 void THostAuth::SetDetails(Int_t level, const char *details)
 {
@@ -258,7 +270,8 @@ void THostAuth::Print(const char *proc)
 {
    // Print object content.
 
-   Info("Print","%s +------------------------------------------------------------------+",proc);
+   Info("Print",
+   "%s +------------------------------------------------------------------+",proc);
    Info("Print","%s + Host:%s - User:%s - # of available methods:%d",
          proc, fHost.Data(), fUser.Data(), fNumMethods);
    int i = 0;
@@ -266,15 +279,17 @@ void THostAuth::Print(const char *proc)
       Info("Print","%s + Method: %d (%s)  Details:%s", proc, fMethods[i],
            TAuthenticate::GetAuthMethod(fMethods[i]), fDetails[i].Data());
    }
-   Info("Print","%s +------------------------------------------------------------------+",proc);
+   Info("Print",
+   "%s +------------------------------------------------------------------+",proc);
 }
 
 //______________________________________________________________________________
 void THostAuth::PrintEstablished()
 {
-   // Print info about estalished authentication vis-a-vis of this Host.
+   // Print info about established authentication vis-a-vis of this Host.
 
-   Info("PrintEstablished","+------------------------------------------------------------------------------+");
+   Info("PrintEstablished",
+   "+------------------------------------------------------------------------------+");
    Info("PrintEstablished","+ Host:%s - Number of Established Authentications: %d",
          fHost.Data(), fEstablished->GetSize());
 
@@ -285,7 +300,8 @@ void THostAuth::PrintEstablished()
       while ((ai = (TAuthDetails*) next()))
          ai->Print("e");
    }
-   Info("PrintEstablished","+------------------------------------------------------------------------------+");
+   Info("PrintEstablished",
+   "+------------------------------------------------------------------------------+");
 }
 
 //______________________________________________________________________________
diff --git a/net/src/TNetFile.cxx b/net/src/TNetFile.cxx
index df41eb7c13e..e5006cec89a 100644
--- a/net/src/TNetFile.cxx
+++ b/net/src/TNetFile.cxx
@@ -1,4 +1,4 @@
-// @(#)root/net:$Name:  $:$Id: TNetFile.cxx,v 1.37 2003/09/21 21:38:31 rdm Exp $
+// @(#)root/net:$Name:  $:$Id: TNetFile.cxx,v 1.38 2003/10/22 18:48:36 rdm Exp $
 // Author: Fons Rademakers   14/08/97
 
 /*************************************************************************
@@ -474,21 +474,9 @@ void TNetFile::ConnectServer(Int_t *stat, EMessageTypes *kind, Int_t netopt,
 
    // Authenticate remotely
    if (gDebug > 2) Info("Authenticate", "User from Url: %s", fUrl.GetUser());
-#if 0
-   if (!strcmp(fUrl.GetProtocol(), "roots")) {
-      auth = new TAuthenticate(fSocket, fUrl.GetHost(),
-                               Form("roots:%d", fProtocol), fUrl.GetUser());
-   } else if (!strcmp(fUrl.GetProtocol(), "rootk")) {
-      auth = new TAuthenticate(fSocket, fUrl.GetHost(),
-                               Form("rootk:%d", fProtocol), fUrl.GetUser());
-   } else {
-      auth = new TAuthenticate(fSocket, fUrl.GetHost(),
-                               Form("rootd:%d", fProtocol), fUrl.GetUser());
-   }
-#else
    auth = new TAuthenticate(fSocket, fUrl.GetHost(),
                 Form("%s:%d",fUrl.GetProtocol(),fProtocol), fUrl.GetUser());
-#endif
+
    // Attempt authentication
    if (!auth->Authenticate()) {
       Error("TNetFile", "%s authentication failed for host %s",
diff --git a/proof/inc/TProofServ.h b/proof/inc/TProofServ.h
index f7430f4941a..74a2ba6502a 100644
--- a/proof/inc/TProofServ.h
+++ b/proof/inc/TProofServ.h
@@ -1,4 +1,4 @@
-// @(#)root/proof:$Name:  $:$Id: TProofServ.h,v 1.17 2003/10/07 14:03:03 rdm Exp $
+// @(#)root/proof:$Name:  $:$Id: TProofServ.h,v 1.18 2003/10/07 21:09:55 rdm Exp $
 // Author: Fons Rademakers   16/02/97
 
 /*************************************************************************
@@ -88,7 +88,7 @@ private:
    Int_t       LockPackage() { return LockDir(fPackageLock); }
    Int_t       UnlockPackage() { return UnlockDir(fPackageLock); }
    Int_t       CheckAuth(Int_t sec, char **det);
-   void        ReadProofAuth();
+   void        RecvHostAuth();
    void        CollectAuthInfo();
 
 public:
diff --git a/proof/src/TProofServ.cxx b/proof/src/TProofServ.cxx
index 36143c418c5..0f605a782a0 100644
--- a/proof/src/TProofServ.cxx
+++ b/proof/src/TProofServ.cxx
@@ -1,4 +1,4 @@
-// @(#)root/proof:$Name:  $:$Id: TProofServ.cxx,v 1.57 2003/11/05 18:11:38 rdm Exp $
+// @(#)root/proof:$Name:  $:$Id: TProofServ.cxx,v 1.58 2003/11/06 15:08:36 rdm Exp $
 // Author: Fons Rademakers   16/02/97
 
 /*************************************************************************
@@ -328,6 +328,9 @@ TProofServ::TProofServ(int *argc, char **argv)
 
    gProofServ = this;
 
+   // Collect authentication info ...
+   CollectAuthInfo();
+
    // if master, start slave servers
    if (IsMaster()) {
       TString master = "proof://__master__";
@@ -337,9 +340,6 @@ TProofServ::TProofServ(int *argc, char **argv)
          master += a.GetPort();
       }
 
-      // Collect authentication info ...
-      CollectAuthInfo();
-
       fProof = new TProof(master, fConfFile, fConfDir, fLogLevel);
       SendLogFile();
    }
@@ -1468,8 +1468,6 @@ void TProofServ::Setup()
              gROOT->IsProofServ()) {
             // We got a file name ... extract the tmp directory path
             TString KeyFile = lApp->Argv()[3];
-            Int_t lTmp = KeyFile.Index("/proofauth", strlen("/proofauth"), 0, TString::kExact);
-            KeyFile.Resize(lTmp);
             KeyFile += "/rpk_";
             KeyFile += retval;
 
@@ -1520,6 +1518,9 @@ void TProofServ::Setup()
 
    delete mess;
 
+   // Recv auth info transmitted from the client
+   RecvHostAuth();
+
    // deny write access for group and world
    gSystem->Umask(022);
 
@@ -1703,155 +1704,12 @@ TProofServ *TProofServ::This()
    return gProofServ;
 }
 
-//______________________________________________________________________________
-void TProofServ::ReadProofAuth()
-{
-   // Read the content of a proofauth.xxx file, if exists, create related
-   // THostAuth and add them to the authInfo list.
-
-   TList     *authInfo = 0;
-   THostAuth *hostAuth = 0;
-
-   PDB(kGlobal,2) Info("ReadProofAuth","enter ...");
-
-   // Get pointer to list with authentication info
-   authInfo = TAuthenticate::GetAuthInfo();
-
-   // Check if we got a file name from the calling process
-   TApplication *lApp = gROOT->GetApplication();
-   if (lApp) {
-      if (lApp->Argc() > 3) {
-         // We got a file name ...
-         char *FilePA = StrDup(lApp->Argv()[3]);
-         PDB(kGlobal,3) Info("ReadProofAuth","filename is: %s", FilePA);
-
-         // Check accessibility ...
-         if (!gSystem->AccessPathName(FilePA, kReadPermission)) {
-            // Now open it
-            FILE *fpa = fopen(FilePA, "r");
-            if (fpa) {
-               // now read it
-               char  line[1024];
-               int   i, nmet, meth[kMAXSEC], len;
-               char *ptr, *pend, *host, *user, *rest, *det[kMAXSEC];
-               while (fgets(line, sizeof(line),fpa)) {
-                  // Reset entry
-                  for (i = 0; i < kMAXSEC; i++) { meth[i]= -1; det[i]= 0; }
-                  // get read of CR ... if any
-                  if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0';
-                  // Now decode
-                  rest = new char[strlen(line)+1]; rest[0]='\0';
-                  ptr  = line;
-
-                  host = new char[strlen(line)+1]; host[0]='\0';
-                  sscanf(ptr+2, "%s %s", host, rest);
-                  ptr = strstr(ptr, rest);
-
-                  user = new char[strlen(line)+1]; user[0]='\0';
-                  sscanf(ptr+2, "%s %s", user, rest);
-                  if (!strcmp(user, "any")) user[0] = '\0';
-                  ptr = strstr(ptr, rest);
-
-                  sscanf(ptr+2, "%d %s", &nmet, rest);
-                  PDB(kGlobal,3)
-                      Info("ReadProofAuth","host user nmet: %s %s %d",host,user,nmet);
-
-                  ptr = strstr(ptr, rest);
-                  for (i = 0; i < nmet; i++) {
-                     sscanf(ptr+1, "%d %s", &meth[i], rest);
-                     ptr = strstr(ptr, rest);
-
-                     PDB(kGlobal,3) Info("ReadProofAuth","meth[%d]: %d (%s)",i,meth[i]);
-
-                     pend = strstr(ptr+1,"'");
-                     len = pend-ptr;
-                     det[i] = new char[len+5];
-                     strncpy(det[i], ptr, len);
-                     det[i][len]='\0';
-                     // Turn off prompt
-                     char *ppt = strstr(det[i], "pt:");
-                     if (ppt) {
-                        if (!strncmp(ppt+3,"yes",3)) {
-                           ppt[3]='n'; ppt[4]='o'; ppt[5]=' ';
-                        }
-                        if (!strncmp(ppt+3,"1",1)) {
-                           ppt[3]='0';
-                        }
-                     }
-                     PDB(kGlobal,3) Info("ReadProofAuth", "det[%d]: %s",i,det[i]);
-                     ptr = strstr(pend+1, "'");
-                  }
-                  // Check if a HostAuth object for this (host,user) pair already exists
-                  hostAuth = TAuthenticate::GetHostAuth(host,user);
-                  if (!hostAuth) {
-                     // Create HostAuth object ...
-                     hostAuth = new THostAuth(host,user,nmet,meth,(char **)det);
-                     PDB(kGlobal,3) hostAuth->Print();
-
-                     // ... and add it to the list (static in TAuthenticate)
-                     authInfo->Add(hostAuth);
-                  } else {
-                     PDB(kGlobal,3) {
-                        Info("ReadProofAuth", "updating existing THostAuth for (%s,%s)",host,user);
-                        hostAuth->Print();
-                     }
-
-                    int nold = hostAuth->NumMethods();
-                    int i,j;
-                    for (i = 0; i < nmet; i++ ) {
-                       int jm = -1;
-                       for (j = 0; j < nold; j++ ) {
-                          if (meth[i] == hostAuth->GetMethods(j)) {
-                             jm= j; break;
-                          }
-                       }
-                       if (jm == -1) {
-                          // Add a method ...
-                          hostAuth->AddMethod(meth[i], det[i]);
-                       } else {
-                          // Set a new details string ...
-                          hostAuth->SetDetails(meth[i], det[i]);
-                       }
-                    }
-                 }
-                 // Delete allocate memory
-                 if (host) delete[] host;
-                 if (user) delete[] user;
-                 if (rest) delete[] rest;
-                 for (i = 0; i < kMAXSEC; i++) {
-                    if (det[i]) delete[] det[i];
-                    det[i] = 0; meth[i] = -1;
-                  }
-                  nmet = 0;
-               }
-               // Close the file
-               fclose(fpa);
-               // Unlink (=delete) the file
-               gSystem->Unlink(FilePA);
-            } else {
-               PDB(kGlobal,3)
-                  Info("ReadProofAuth","file %s cannot be opened", FilePA);
-            }
-         } else {
-            PDB(kGlobal,3)
-               Info("ReadProofAuth","file %s either non existing or not readable", FilePA);
-         }
-         delete [] FilePA;
-      } else {
-         PDB(kGlobal,3)
-            Info("ReadProofAuth","no file name received from calling process");
-      }
-   } else {
-      PDB(kGlobal,3) Info("ReadProofAuth","unable to access calling arguments");
-   }
-}
-
 //______________________________________________________________________________
 void TProofServ::CollectAuthInfo()
 {
    // Collect information needed for authentication to slaves.
-   // Sources are proof.conf and proofauth.xxx files.
-   // THostAuth objects are created accordingly and added to the authInfo list.
+   // Source is proof.conf and THostAuth objects are created accordingly
+   // and added to the authInfo list.
 
    TList     *authInfo = 0;
    THostAuth *hostAuth = 0;
@@ -1873,7 +1731,7 @@ void TProofServ::CollectAuthInfo()
    for (i = 0; i < kMAXSEC; i++){
       if (i == 0 && fUser != "" && fPasswd != "") {
          AuthAvailable[i] = 1;
-         AuthDet[i] = StrDup(Form("pt:0 ru:0 us:%s", fUser.Data()));
+         AuthDet[i] = StrDup(Form("pt:0 ru:1 us:%s", fUser.Data()));
       } else {
          AuthAvailable[i] = CheckAuth(i, &AuthDet[i]);
       }
@@ -2031,29 +1889,13 @@ void TProofServ::CollectAuthInfo()
                   PDB(kGlobal,3) hostAuth->Print();
                }
 
-#if 0
-               // If 'host' is ourselves, then use rfio (to setup things correctly)
-               // Check and save the host FQDN ...
-               static TString LocalFqdn;
-               if (LocalFqdn == "") {
-                  TInetAddress addr = gSystem->GetHostByName(gSystem->HostName());
-                  if (addr.IsValid()) {
-                     LocalFqdn = addr.GetHostName();
-                     if (LocalFqdn == "UnNamedHost")
-                        LocalFqdn = addr.GetHostAddress();
-	          }
-	       }
-               if (SlaveFqdn == LocalFqdn || SlaveFqdn.Contains("localhost"))
-                  hostAuth->SetFirst((int)TAuthenticate::kRfio);
-#endif
-
                // CleanUp memory
                int ks;
                for (ks = 0; ks < nSecs; ks++) {
                   if (fDets[ks]) delete[] fDets[ks];
                }
-	    } // strcmp "slave"
-	 } // fgets
+            } // strcmp "slave"
+         } // fgets
       } // fopen
 
       // close file
@@ -2097,22 +1939,16 @@ void TProofServ::CollectAuthInfo()
    for (Int_t ks = 0; ks < 2; ks++) {
       if (fDets[ks]) delete[] fDets[ks];
    }
-
-   // Read info transmitted from the client ...
-   ReadProofAuth();
 }
 
-
 //______________________________________________________________________________
 Int_t TProofServ::CheckAuth(Int_t cSec, char **Det)
 {
    // Check if the authentication method can be attempted for the client.
 
-   const char sshid[3][20] = { ".ssh/identity", ".ssh/id_dsa", ".ssh/id_rsa" };
-   const char netrc[2][20] = { ".netrc", ".rootnetrc" };
+   const char sshid[3][20] = { "/.ssh/identity", "/.ssh/id_dsa", "/.ssh/id_rsa" };
+   const char netrc[2][20] = { "/.netrc", "/.rootnetrc" };
    Int_t ok          = 0;
-   char *home        = 0;
-   char *infofile    = 0;
    char *details     = 0;
    char *user        = 0;
 
@@ -2122,17 +1958,16 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det)
       user = StrDup(pw->fUser);
       delete pw;
    } else {
-      Info("CheckAuth", "not properly logged on (getpwuid unable to find relevant info)!");
+      Info("CheckAuth",
+           "not properly logged on (getpwuid unable to find relevant info)!");
       return ok;
    }
 
    // UsrPwd
    if (cSec == (Int_t) TAuthenticate::kClear) {
-      home = StrDup(getenv("HOME"));
-      infofile = new char[sizeof(home)+25];
       Int_t i;
       for (i = 0; i < 2; i++) {
-         sprintf(infofile,"%s/%s",home,netrc[i]);
+         TString infofile = TString(gSystem->HomeDirectory())+TString(netrc[i]);
          if (!gSystem->AccessPathName(infofile, kReadPermission)) ok = 1;
       }
       if (ok == 1) {
@@ -2205,11 +2040,9 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det)
 
    // SSH
    if (cSec == (Int_t) TAuthenticate::kSSH) {
-      home = StrDup(getenv("HOME"));
-      infofile = new char[sizeof(home)+25];
       int i;
       for (i = 0; i < 3; i++) {
-         sprintf(infofile,"%s/%s",home,sshid[i]);
+         TString infofile = TString(gSystem->HomeDirectory())+TString(sshid[i]);
          if (!gSystem->AccessPathName(infofile,kReadPermission)) ok = 1;
       }
       if (ok == 1) {
@@ -2228,10 +2061,6 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det)
    // Fill output, if relevant ...
    if (details) { *Det= StrDup(details); delete [] details; }
 
-   // CleanUp remaining stuff ...
-   if (home)     delete [] home;
-   if (infofile) delete [] infofile;
-
    PDB(kGlobal,3) {
       if (ok == 1) {
          Info("CheckAuth","meth: %d ... is available: details: %s", cSec, *Det);
@@ -2243,3 +2072,150 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det)
    // return
    return ok;
 }
+
+//______________________________________________________________________________
+void TProofServ::RecvHostAuth()
+{
+   // Receive from TSlave directives for future authentications, create related
+   // THostAuth and add them to the authInfo list.
+
+   TList     *authInfo = 0;
+   THostAuth *hostAuth = 0;
+
+   PDB(kGlobal,2) Info("RecvHostAuth", "enter ...");
+
+   // Get pointer to list with authentication info
+   authInfo = TAuthenticate::GetAuthInfo();
+
+   // Receive buffer
+   Int_t kind;
+   const Int_t kBUF = 2048;
+   char buf[kBUF];
+   Int_t nr = fSocket->Recv(buf, kBUF, kind);
+   if (nr < 0 || kind != kPROOF_SENDHOSTAUTH) {
+      Error("RecvHostAuth", "received: kind: %d (%d bytes)", kind, nr);
+      return;
+   }
+   PDB(kGlobal,2)
+      Info("RecvHostAuth", "received: (%d bytes) %s", nr, buf);
+   char rest[kBUF], host[kBUF], user[kBUF];
+   Int_t i, nmet, meth[kMAXSEC], len;
+   char *ptr = 0, *pend = 0, *det[kMAXSEC] = {0};
+   while (strcmp(buf, "END")) {
+      // Clean buffer
+      Int_t nc = (nr < kBUF)? nr : kBUF ;
+      buf[nc] = '\0';
+
+      // Init
+      rest[0] = '\0';
+      host[0] = '\0';
+      user[0] = '\0';
+
+      // Now decode
+      ptr = strstr(buf, "h:");  // The host string begins with "h:"
+      sscanf(ptr+2, "%s %s", host, rest);
+
+      ptr = strstr(ptr, "u:");  // The user string begins with "u:"
+      sscanf(ptr+2, "%s %s", user, rest);
+      if (!strcmp(user, "any")) user[0] = '\0';
+
+      ptr = strstr(ptr, "n:");  // Methods info begins with "n:"
+      sscanf(ptr+2, "%d %s", &nmet, rest);
+
+      // Notify if required
+      PDB(kGlobal,3)
+          Info("RecvHostAuth", "host user nmet: %s %s %d", host, user, nmet);
+
+      // Details for methods should follow in the form of single-quote
+      // delimited strings with method number and details, eg
+      //   '0 pt:0 ru:1 us:qwerty'
+      ptr = strstr(ptr, rest);
+      for (i = 0; i < nmet; i++) {
+
+         // First the method number ...
+         sscanf(ptr+1, "%d %s", &meth[i], rest);
+         PDB(kGlobal,3)
+            Info("RecvHostAuth", "meth[%d]: %d (%s)", i, meth[i]);
+
+         // ... then the details
+         ptr = strstr(ptr, rest);
+         pend = strstr(ptr+1, "'");
+         len = pend-ptr;
+         det[i] = new char[len+5];
+         strncpy(det[i], ptr, len);
+         det[i][len] = '\0';
+         // Make sure that prompt is off
+         char *ppt = strstr(det[i], "pt:");
+         if (ppt) {
+            if (!strncasecmp(ppt+3, "yes", 3)) {
+               ppt[3] = 'n'; ppt[4] = 'o'; ppt[5] = ' ';
+            }
+            if (!strncmp(ppt+3, "1", 1)) {
+               ppt[3] = '0';
+            }
+         }
+         PDB(kGlobal,3)
+            Info("RecvHostAuth", "det[%d]: %s", i, det[i]);
+         ptr = strstr(pend+1, "'");
+      }
+
+      // Check if a HostAuth object for this (host,user) pair already exists
+      hostAuth = TAuthenticate::GetHostAuth(host, user);
+      if (!hostAuth || strcmp(hostAuth->GetHost(), host)) {
+         // Create HostAuth object ...
+         hostAuth = new THostAuth(host, user, nmet, meth, (char **)det);
+         PDB(kGlobal,3) hostAuth->Print();
+
+         // ... and add it to the list (static in TAuthenticate)
+         authInfo->Add(hostAuth);
+      } else {
+         PDB(kGlobal,3) {
+            Info("RecvHostAuth", "updating existing THostAuth for (%s,%s)", host, user);
+            hostAuth->Print();
+         }
+
+         Int_t nold = hostAuth->NumMethods();
+         Int_t i,j;
+         // We add new methods or update details; in any case the
+         // should be the one we have found, so we start from the
+         // last ...
+         for (i = nmet-1; i > -1; i-- ) {
+            int jm = -1;
+            for (j = 0; j < nold; j++ ) {
+               if (meth[i] == hostAuth->GetMethods(j)) {
+                  jm = j;
+                  break;
+               }
+            }
+            if (jm == -1) {
+               // Add method as first ...
+               hostAuth->SetFirst(meth[i], det[i]);
+            } else {
+               // Set method as first ...
+               hostAuth->SetFirst(meth[i]);
+               // ... and update details string
+               hostAuth->SetDetails(meth[i], det[i]);
+            }
+         }
+      }
+      // Delete allocate memory
+      for (i = 0; i < kMAXSEC; i++) {
+         if (det[i])
+            delete[] det[i];
+         det[i] = 0;
+         meth[i] = -1;
+      }
+      nmet = 0;
+      ptr = 0;
+      pend = 0;
+
+      // Get the next one
+      nr = fSocket->Recv(buf, kBUF, kind);
+      if (nr < 0 || kind != kPROOF_SENDHOSTAUTH) {
+         Info("RecvHostAuth","Error: received: kind: %d (%d bytes)", kind, nr);
+         return;
+      }
+      PDB(kGlobal,2)
+         Info("RecvHostAuth"," received: (%d bytes) %s", nr, buf);
+   }
+}
diff --git a/proof/src/TSlave.cxx b/proof/src/TSlave.cxx
index 9f35ec66348..1ff5489e100 100644
--- a/proof/src/TSlave.cxx
+++ b/proof/src/TSlave.cxx
@@ -1,4 +1,4 @@
-// @(#)root/proof:$Name:  $:$Id: TSlave.cxx,v 1.18 2003/10/07 14:03:03 rdm Exp $
+// @(#)root/proof:$Name:  $:$Id: TSlave.cxx,v 1.19 2003/10/07 21:09:55 rdm Exp $
 // Author: Fons Rademakers   14/02/97
 
 /*************************************************************************
@@ -116,14 +116,6 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf,
             Info("TSlave", "Remote Client: fUser is .... %s", proof->fUser.Data());
          }
 
-         if (ProofdProto > 6) {
-            // Now we send authentication details to access, eg, data servers
-            // not in the proof cluster and to be propagated to slaves.
-            // This is triggered by the 'proofserv <dserv1> <dserv2> ...'
-            // card in .rootauthrc
-            SendHostAuth(this, 0);
-         }
-
       } else {
 
          // we are a master server... authenticate either:
@@ -164,10 +156,6 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf,
             auth->GetHostAuth()->PrintEstablished();
             Info("TSlave", "Master Server: fUser is .... %s", fUser.Data());
          }
-
-         if (ProofdProto > 6) {
-            SendHostAuth(this, 1);
-         }
       }
 
       // fSecurity is the method successfully tried ...
@@ -211,10 +199,18 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf,
          TString passwd = "";
          Bool_t  pwhash = kFALSE;
          Bool_t  srppwd = kFALSE;
+         Bool_t  sndsrp = kFALSE;
 
-         if (!fProof->IsMaster() &&
-            (fSecurity == TAuthenticate::kClear ||
-            (fSecurity == TAuthenticate::kSRP && gEnv->GetValue("Proofd.SendSRPPwd",0)))) {
+         if (!fProof->IsMaster()) {
+            if (gEnv->GetValue("Proofd.SendSRPPwd",0))
+               sndsrp = kTRUE;
+         } else {
+            if (fProof->fSRPPwd && fProof->fPasswd != "")
+               sndsrp = kTRUE;
+         }
+
+         if (fSecurity == TAuthenticate::kClear ||
+            (fSecurity == TAuthenticate::kSRP && sndsrp)) {
 
             // Send offset to identify remotely the public part of RSA key
             fSocket->Send(RemoteOffSet,kROOTD_RSAKEY);
@@ -240,7 +236,7 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf,
                TMessage mess;
                mess << passwd;
                fSocket->Send(mess);
-	    }
+            }
 
          } else {
 
@@ -251,12 +247,23 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf,
 
          TMessage mess;
          if (!fProof->IsMaster())
-	   mess << fProof->fUser << pwhash << srppwd << fProof->fConfFile;
+            mess << fProof->fUser << pwhash << srppwd << fProof->fConfFile;
          else
-	   mess << fProof->fUser << pwhash << srppwd << fOrdinal;
+            mess << fProof->fUser << pwhash << srppwd << fOrdinal;
 
          fSocket->Send(mess);
 
+         if (ProofdProto > 6) {
+            // Now we send authentication details to access, eg, data servers
+            // not in the proof cluster and to be propagated to slaves.
+            // This is triggered by the 'proofserv <dserv1> <dserv2> ...'
+            // card in .rootauthrc
+            if (!fProof->IsMaster())
+               SendHostAuth(this, 0);
+            else
+               SendHostAuth(this, 1);
+         }
+
          // set some socket options
          fSocket->SetOption(kNoDelay, 1);
       }
diff --git a/proofd/src/proofd.cxx b/proofd/src/proofd.cxx
index c9c718210ad..26a3761c393 100644
--- a/proofd/src/proofd.cxx
+++ b/proofd/src/proofd.cxx
@@ -1,4 +1,4 @@
-// @(#)root/proofd:$Name:  $:$Id: proofd.cxx,v 1.51 2003/10/27 09:48:35 rdm Exp $
+// @(#)root/proofd:$Name:  $:$Id: proofd.cxx,v 1.52 2003/10/28 16:32:43 rdm Exp $
 // Author: Fons Rademakers   02/02/97
 
 /*************************************************************************
@@ -235,7 +235,6 @@ int     gDebug                   = 0;
 int     gForegroundFlag          = 0;
 int     gInetdFlag               = 0;
 int     gMaster                  =-1;
-int     gPort                    = 0;
 int     gProtocol                = 8;       // increase when protocol changes
 char    gRcFile[kMAXPATHLEN]     = { 0 };
 int     gRootLog                 = 0;
@@ -704,16 +703,18 @@ void Authenticate()
                   gAuthListSent = 1;
                   goto next;
                } else {
-                  Error(ErrFatal,kErrNotAllowed, "Authenticate: method not in the list sent to the client");
+                  Error(ErrFatal,kErrNotAllowed,
+                       "Authenticate: method not in the list sent to the client");
                }
             } else
-               Error(ErrFatal,kErrConnectionRefused, "Authenticate: connection refused from host %s", gOpenHost);
+               Error(ErrFatal,kErrConnectionRefused,
+                       "Authenticate: connection refused from host %s", gOpenHost);
          }
 
          // Then check if a previous authentication exists and is valid
          // ReUse does not apply for RFIO
          if (kind != kROOTD_RFIO && ProofdReUseAuth(recvbuf, kind))
-            goto recvauth;
+            goto next;
       }
 
       switch (kind) {
@@ -753,7 +754,8 @@ void Authenticate()
       if (gClientProtocol > 8) {
 
          if (gDebug > 2)
-            ErrorInfo("Authenticate: here we are: kind:%d -- Meth:%d -- gAuth:%d -- gNumLeft:%d", kind, Meth, gAuth, gNumLeft);
+            ErrorInfo("Authenticate: kind:%d -- Meth:%d -- gAuth:%d -- gNumLeft:%d",
+                      kind, Meth, gAuth, gNumLeft);
 
          // If authentication failure, check if other methods could be tried ...
          if ((Meth != -1 || kind==kROOTD_PASS) && gAuth == 0) {
@@ -768,39 +770,6 @@ void Authenticate()
          }
       }
 
-recvauth:
-      // If authentication successfull, receive info for later authentications
-      if (gAuth == 1 && gClientProtocol > 8) {
-
-         sprintf(gFilePA, "%s/proofauth.%ld", gTmpDir, (long)getpid());
-         if (gDebug > 2) ErrorInfo("Authenticate: file with hostauth info is: %s", gFilePA);
-
-         FILE *fpa = fopen(gFilePA, "w");
-         if (fpa == 0) {
-            ErrorInfo("Authenticate: error creating file: %s", gFilePA);
-            goto next;
-         }
-
-         // Receive buffer
-         EMessageTypes kindauth;
-         int nr = NetRecv(recvbuf, kMaxBuf, kindauth);
-         if (nr < 0 || kindauth != kPROOF_SENDHOSTAUTH)
-            ErrorInfo("Authenticate: SENDHOSTAUTH: received: %d (%d bytes)", kindauth, nr);
-         if (gDebug > 2) ErrorInfo("Authenticate: received: (%d) %s", nr, recvbuf);
-         while (strcmp(recvbuf, "END")) {
-            // Clean buffer
-            recvbuf[nr+1] = '\0';
-            // Write it to file
-            fprintf(fpa, "%s\n", recvbuf);
-            // Get the next one
-            nr = NetRecv(recvbuf, kMaxBuf, kindauth);
-            if (nr < 0 || kindauth != kPROOF_SENDHOSTAUTH)
-               ErrorInfo("Authenticate: SENDHOSTAUTH: received: %d (%d bytes)", kindauth, nr);
-            if (gDebug > 2) ErrorInfo("Authenticate: received: (%d) %s", nr, recvbuf);
-         }
-         // Close suth file
-         fclose(fpa);
-      }
 next:
       continue;
    }
@@ -1007,7 +976,7 @@ void ProofdExec()
    argvv[0] = arg0;
    argvv[1] = (char *)(gMaster ? "proofserv" : "proofslave");
    argvv[2] = gConfDir;
-   argvv[3] = gFilePA;
+   argvv[3] = gTmpDir;
    argvv[4] = gOpenHost;
    sprintf(rpid, "%d", gRemPid);
    argvv[5] = rpid;
@@ -1130,8 +1099,10 @@ int main(int argc, char **argv)
             case 'b':
                if (--argc <= 0) {
                   if (!gInetdFlag)
-                     fprintf(stderr, "-b requires a buffersize in bytes as argument\n");
-                  Error(ErrFatal, -1, "-b requires a buffersize in bytes as argument");
+                     fprintf(stderr,
+                             "-b requires a buffersize in bytes as argument\n");
+                  Error(ErrFatal, -1,
+                             "-b requires a buffersize in bytes as argument");
                }
                tcpwindowsize = atoi(*++argv);
                break;
@@ -1139,8 +1110,10 @@ int main(int argc, char **argv)
             case 'T':
                if (--argc <= 0) {
                   if (!gInetdFlag)
-                     fprintf(stderr, "-T requires a dir path for temporary files [/usr/tmp]\n");
-                  Error(ErrFatal, kErrFatal, "-T requires a dir path for temporary files [/usr/tmp]");
+                     fprintf(stderr,
+                             "-T requires a dir path for temporary files [/usr/tmp]\n");
+                  Error(ErrFatal, kErrFatal,
+                             "-T requires a dir path for temporary files [/usr/tmp]");
                }
                sprintf(gTmpDir, "%s", *++argv);
                break;
@@ -1148,8 +1121,10 @@ int main(int argc, char **argv)
             case 's':
                if (--argc <= 0) {
                   if (!gInetdFlag)
-                     fprintf(stderr, "-s requires as argument a port number for the sshd daemon\n");
-                  Error(ErrFatal, kErrFatal, "-s requires as argument a port number for the sshd daemon");
+                     fprintf(stderr,
+                             "-s requires as argument a port number for the sshd daemon\n");
+                  Error(ErrFatal, kErrFatal,
+                             "-s requires as argument a port number for the sshd daemon");
                }
                gSshdPort = atoi(*++argv);
                break;
@@ -1184,8 +1159,10 @@ int main(int argc, char **argv)
             case 'C':
                if (--argc <= 0) {
                   if (!gInetdFlag)
-                     fprintf(stderr, "-C requires a file name for the host certificates file location\n");
-                  Error(ErrFatal, -1, "-C requires a file name for the host certificates file location");
+                     fprintf(stderr,
+                             "-C requires a file name for the host certificates file location\n");
+                  Error(ErrFatal, -1,
+                             "-C requires a file name for the host certificates file location");
                }
                sprintf(gHostCertConf, "%s", *++argv);
                break;
@@ -1214,15 +1191,17 @@ int main(int argc, char **argv)
       strncpy(gConfDir, *argv, kMAXPATHLEN-1);
       gConfDir[kMAXPATHLEN-1] = 0;
       sprintf(gExecDir, "%s/bin", gConfDir);
-      sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess);
+      sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc);
    } else {
       // try to guess the config directory...
 #ifndef ROOTPREFIX
       if (getenv("ROOTSYS")) {
          strcpy(gConfDir, getenv("ROOTSYS"));
          sprintf(gExecDir, "%s/bin", gConfDir);
-         sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess);
-         if (gDebug > 0) ErrorInfo("main: no config directory specified using ROOTSYS (%s)", gConfDir);
+         sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc);
+         if (gDebug > 0)
+            ErrorInfo("main: no config directory specified using ROOTSYS (%s)",
+                      gConfDir);
       } else {
          if (!gInetdFlag)
             fprintf(stderr, "proofd: no config directory specified\n");
@@ -1235,7 +1214,7 @@ int main(int argc, char **argv)
       strcpy(gExecDir, ROOTBINDIR);
 #endif
 #ifdef ROOTETCDIR
-      sprintf(gAuthAllow, "%s/%s", ROOTETCDIR, kDaemonAccess);
+      sprintf(gSystemDaemonRc, "%s/system%s", ROOTETCDIR, kDaemonRc);
 #endif
    }
 
@@ -1244,8 +1223,10 @@ int main(int argc, char **argv)
    sprintf(arg0, "%s/bin/proofserv", gConfDir);
    if (access(arg0, X_OK) == -1) {
       if (!gInetdFlag)
-         fprintf(stderr, "proofd: incorrect config directory specified (%s)\n", gConfDir);
-      Error(ErrFatal, -1, "main: incorrect config directory specified (%s)", gConfDir);
+         fprintf(stderr,
+                 "proofd: incorrect config directory specified (%s)\n", gConfDir);
+      Error(ErrFatal, -1,
+                 "main: incorrect config directory specified (%s)", gConfDir);
    }
 
    // Log to stderr if not started as daemon ...
diff --git a/rootd/src/rootd.cxx b/rootd/src/rootd.cxx
index 41602cbef2c..eb613e51fe0 100644
--- a/rootd/src/rootd.cxx
+++ b/rootd/src/rootd.cxx
@@ -1,4 +1,4 @@
-// @(#)root/rootd:$Name:  $:$Id: rootd.cxx,v 1.67 2003/10/27 09:48:35 rdm Exp $
+// @(#)root/rootd:$Name:  $:$Id: rootd.cxx,v 1.68 2003/10/28 16:32:43 rdm Exp $
 // Author: Fons Rademakers   11/08/97
 
 /*************************************************************************
@@ -2359,7 +2359,7 @@ int main(int argc, char **argv)
       strncpy(gConfDir, *argv, kMAXPATHLEN-1);
       gConfDir[kMAXPATHLEN-1] = 0;
       sprintf(gExecDir, "%s/bin", gConfDir);
-      sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess);
+      sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc);
    } else {
       // try to guess the config directory...
 #ifndef ROOTPREFIX
@@ -2367,7 +2367,7 @@ int main(int argc, char **argv)
          if (getenv("ROOTSYS")) {
             strcpy(gConfDir, getenv("ROOTSYS"));
             sprintf(gExecDir, "%s/bin", gConfDir);
-            sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess);
+            sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc);
             if (gDebug > 0) ErrorInfo("main: no config directory specified using ROOTSYS (%s)", gConfDir);
          } else {
             if (!gInetdFlag)
@@ -2382,7 +2382,7 @@ int main(int argc, char **argv)
       strcpy(gExecDir, ROOTBINDIR);
 #endif
 #ifdef ROOTETCDIR
-      sprintf(gAuthAllow, "%s/%s", ROOTETCDIR, kDaemonAccess);
+      sprintf(gSystemDaemonRc, "%s/system%s", ROOTETCDIR, kDaemonRc);
 #endif
    }
 
@@ -2392,7 +2392,8 @@ int main(int argc, char **argv)
       // Also initialize the network connection - create the socket
       // and bind our well-know address to it.
 
-      int fdkeep = NetInit(gService, gPort1, gPort2, tcpwindowsize);
+      gPort = gPort1;
+      int fdkeep = NetInit(gService, gPort, gPort2, tcpwindowsize);
       if (!gForegroundFlag) DaemonStart(1, fdkeep, kROOTD);
    }
 
diff --git a/rpdutils/inc/rpdp.h b/rpdutils/inc/rpdp.h
index 78fef34f057..f9d638e0efc 100644
--- a/rpdutils/inc/rpdp.h
+++ b/rpdutils/inc/rpdp.h
@@ -1,4 +1,4 @@
-// @(#)root/rpdutils:$Name:  $:$Id: rpdp.h,v 1.6 2003/10/07 14:03:03 rdm Exp $
+// @(#)root/rpdutils:$Name:  $:$Id: rpdp.h,v 1.7 2003/10/22 18:48:36 rdm Exp $
 // Author: Gerardo Ganis   7/4/2003
 
 /*************************************************************************
@@ -62,6 +62,7 @@ extern int  gNumAllow;
 extern int  gNumLeft;
 extern int  gOffSet;
 extern int  gParallel;
+extern int  gPort;
 extern int  gRemPid;
 extern int  gReUseAllow;
 extern int  gReUseRequired;
@@ -71,7 +72,7 @@ extern int  gSshdPort;
 
 extern char gAltSRPPass[kMAXPATHLEN];
 extern char gAnonUser[64];
-extern char gAuthAllow[kMAXPATHLEN];
+extern char gSystemDaemonRc[kMAXPATHLEN];
 extern char gExecDir[kMAXPATHLEN];        // for use in rootd ...
 extern char gFile[kMAXPATHLEN];
 extern char gFileLog[kMAXPATHLEN];
@@ -84,7 +85,7 @@ extern char gUser[64];
 extern char gPasswd[64];                  // only used for anonymous access
 
 extern const char *kAuthMeth[kMAXSEC];    // authentication method list
-extern const char kDaemonAccess[];        // file containing daemon access rules
+extern const char kDaemonRc[];        // file containing daemon access rules
 
 extern SigPipe_t gSigPipeHook;
 
@@ -124,7 +125,7 @@ int NetRecv(char *msg, int max);
 int NetOpen(int inetdflag, EService service);
 void NetClose();
 const char *NetRemoteHost();
-int  NetInit(const char *service, int port1, int port2, int tcpwindowsize);
+int  NetInit(const char *service, int &port1, int port2, int tcpwindowsize);
 void NetInit(const char *service, int port, int tcpwindowsize);
 void NetSetOptions(EService service, int sock, int tcpwindowsize);
 
diff --git a/rpdutils/src/net.cxx b/rpdutils/src/net.cxx
index 5b4442a6a9b..a1a9c9f7785 100644
--- a/rpdutils/src/net.cxx
+++ b/rpdutils/src/net.cxx
@@ -1,4 +1,4 @@
-// @(#)root/rpdutils:$Name:  $:$Id: net.cxx,v 1.16 2002/10/28 14:22:51 rdm Exp $
+// @(#)root/rpdutils:$Name:  $:$Id: net.cxx,v 1.1 2003/08/29 10:38:19 rdm Exp $
 // Author: Fons Rademakers   12/08/97
 
 /*************************************************************************
@@ -415,7 +415,7 @@ void NetClose()
 }
 
 //______________________________________________________________________________
-int NetInit(const char *service, int port1, int port2, int tcpwindowsize)
+int NetInit(const char *service, int &port1, int port2, int tcpwindowsize)
 {
    // Initialize the network connection for the server, when it has *not*
    // been invoked by inetd. Used by rootd.
@@ -474,6 +474,7 @@ int NetInit(const char *service, int port1, int port2, int tcpwindowsize)
    }
 
    printf("ROOTD_PORT=%d\n", port);
+   port1 = port;
 
    // And set the listen parameter, telling the system that we're
    // ready to accept incoming connection requests.
@@ -539,7 +540,9 @@ void NetInit(const char *service, int port, int tcpwindowsize)
 
    if (bind(tcp_srv_sock, (struct sockaddr *) &tcp_srv_addr,
             sizeof(tcp_srv_addr)) < 0)
-      Error(gErrSys,-1,"NetInit: can't bind local address (sock: %d) : errno: %d",tcp_srv_sock,GetErrno());
+      Error(gErrSys,-1,
+            "NetInit: can't bind local address (sock: %d) : errno: %d",
+             tcp_srv_sock,GetErrno());
 
    // And set the listen parameter, telling the system that we're
    // ready to accept incoming connection requests.
diff --git a/rpdutils/src/rpdutils.cxx b/rpdutils/src/rpdutils.cxx
index 1d6d38aa389..80c37765118 100644
--- a/rpdutils/src/rpdutils.cxx
+++ b/rpdutils/src/rpdutils.cxx
@@ -1,4 +1,4 @@
-// @(#)root/rpdutils:$Name:  $:$Id: rpdutils.cxx,v 1.21 2003/10/27 17:46:17 rdm Exp $
+// @(#)root/rpdutils:$Name:  $:$Id: rpdutils.cxx,v 1.22 2003/10/28 16:32:43 rdm Exp $
 // Author: Gerardo Ganis    7/4/2003
 
 /*************************************************************************
@@ -192,7 +192,7 @@ const char *kAuthMeth[kMAXSEC] = { "UsrPwd", "SRP", "Krb5", "Globus", "SSH", "Ui
 const char kMethods[]      = "usrpwd srp    krb5   globus ssh    uidgid";
 const char kRootdPass[]    = ".rootdpass";
 const char kSRootdPass[]   = ".srootdpass";
-const char kDaemonAccess[] = "daemon.access"; // file containing daemon access rules
+const char kDaemonRc[]     = ".rootdaemonrc"; // file containing daemon access rules
 
 // To control user access
 char *gUserAllow[kMAXSEC] = { 0 };
@@ -202,7 +202,7 @@ unsigned int gUserIgnLen[kMAXSEC] = { 0 };
 
 char gAltSRPPass[kMAXPATHLEN] = { 0 };
 char gAnonUser[64] = "rootd";
-char gAuthAllow[kMAXPATHLEN] = { 0 }; // path to kDaemonAccess
+char gSystemDaemonRc[kMAXPATHLEN] = { 0 }; // path to kDaemonRc
 char gExecDir[kMAXPATHLEN] = { 0 };   // needed to localize ssh2rpd
 char gFileLog[kMAXPATHLEN] = { 0 };
 char gOpenHost[256] = "????";         // same length as in net.cxx ...
@@ -221,6 +221,7 @@ int gGlobus = -1;
 int gNumAllow = -1;
 int gNumLeft = -1;
 int gOffSet = -1;
+int gPort = 0;
 int gRemPid = -1;
 int gReUseAllow = 0x1F;  // define methods for which previous auth can be reused
 int gRootLog = 0;
@@ -261,7 +262,6 @@ const int kAUTH_KRB_MSK = 0x4;
 const int kAUTH_GLB_MSK = 0x8;
 const int kAUTH_SSH_MSK = 0x10;
 
-
 //______________________________________________________________________________
 static int rpdstrncasecmp(const char *str1, const char *str2, int n)
 {
@@ -1037,14 +1037,24 @@ int RpdCheckAuthAllow(int Sec, char *Host)
    // If 'yes', returns 0, if 'no', returns 1, the number of allowed
    // methods in NumAllow, and the codes of the allowed methods (in order
    // of preference) in AllowMeth. Memory for AllowMeth must be allocated
-   // outside. Info read from gAuthAllow.
+   // outside. Info read from gSystemDaemonRc.
 
    int retval = 1, found = 0;
 
+   char theDaemonRc[kMAXPATHLEN] = { 0 };
+
+   // Check if user has a private daemon access file ...
+   struct passwd *pw = getpwuid(getuid());
+   if (pw != 0) {
+      sprintf(theDaemonRc, "%s/%s", pw->pw_dir, kDaemonRc);
+   }
+   if (pw == 0 || access(theDaemonRc, R_OK)) {
+      strcpy(theDaemonRc, gSystemDaemonRc);
+   }
    if (gDebug > 2)
       ErrorInfo
           ("RpdCheckAuthAllow: Checking file: %s for meth:%d host:%s (gNumAllow: %d)",
-           gAuthAllow, Sec, Host, gNumAllow);
+           theDaemonRc, Sec, Host, gNumAllow);
 
    // Check if info already loaded (not first call ...)
    if (gMethInit == 1) {
@@ -1072,16 +1082,16 @@ int RpdCheckAuthAllow(int Sec, char *Host)
       gMethInit = 1;
 
       // First check if file exists and can be read
-      if (access(gAuthAllow, R_OK)) {
+      if (access(theDaemonRc, R_OK)) {
          ErrorInfo("RpdCheckAuthAllow: can't read file %s (errno: %d)",
-                   gAuthAllow, GetErrno());
+                   theDaemonRc, GetErrno());
          return retval;
       }
       // Open file
-      FILE *ftab = fopen(gAuthAllow, "r");
+      FILE *ftab = fopen(theDaemonRc, "r");
       if (ftab == 0) {
          ErrorInfo("RpdCheckAuthAllow: error opening %s (errno: %d)",
-                   gAuthAllow, GetErrno());
+                   theDaemonRc, GetErrno());
          return retval;
       }
       // Get IP of the host in form of a string
@@ -1116,8 +1126,19 @@ int RpdCheckAuthAllow(int Sec, char *Host)
             nw = sscanf(pstr, "%s %s", host, rest);
             if (nw < 2)
                continue;        // no method defined for this host
-            //         pstr = strstr(line,rest);
             pstr = line + strlen(host) + 1;
+
+            // Check if a service is specified
+            char *pcol = strstr(host, ":");
+            if (pcol) {
+               if (!strstr(pcol+1, gService))
+                  continue;
+               else
+                  host[(int)(pcol-host)] = '\0';
+            }
+            if (strlen(host) == 0)
+               strcpy(host, "default");
+
             if (gDebug > 2)
                ErrorInfo("RpdCheckAuthAllow: found host: %s ", host);
 
@@ -1732,21 +1753,26 @@ void RpdKrb5Auth(const char *sstr)
 
    // get service principal
    const char *service = gService;
-   int port = 0; // need to retrieve that information
 
-   if ((strcmp(gService, "rootd") == 0  && port == 1094) ||
-       (strcmp(gService, "proofd") == 0 && port == 1093)) {
+   if (gDebug > 2)
+      ErrorInfo("RpdKrb5Auth: gService: %s, Port: %d ",gService,gPort);
+
+   if ((strcmp(gService, "rootd") == 0  && gPort == 1094) ||
+       (strcmp(gService, "proofd") == 0 && gPort == 1093)) {
       // keep the real service name
    } else {
       // default to host
       service = "host";
    }
 
+   if (gDebug > 2)
+      ErrorInfo("RpdKrb5Auth: using service: %s ",service);
+
    krb5_principal server;
    if ((retval = krb5_sname_to_principal(gKcontext, 0, service,
                                          KRB5_NT_SRV_HST, &server))) {
       ErrorInfo("RpdKrb5Auth: while generating service name (%s): %d %s",
-                gService, retval, error_message(retval));
+                service, retval, error_message(retval));
       return;
    }
 
@@ -2918,12 +2944,9 @@ void RpdDefaultAuthAllow()
 
    // Kerberos
 #ifdef R__KRB5
-//   if (getuid() == 0) {
-      gAllowMeth[gNumAllow] = 2;
-      gNumAllow++;
-      gNumLeft++;
-//   } else
-//      gHaveMeth[2] = 0;
+   gAllowMeth[gNumAllow] = 2;
+   gNumAllow++;
+   gNumLeft++;
 #else
    // Don't have this method
    gHaveMeth[2] = 0;
diff --git a/srputils/src/SRPAuth.cxx b/srputils/src/SRPAuth.cxx
index 445977d39b4..f79fc4fe5e6 100644
--- a/srputils/src/SRPAuth.cxx
+++ b/srputils/src/SRPAuth.cxx
@@ -1,4 +1,4 @@
-// @(#)root/srputils:$Name:  $:$Id: SRPAuth.cxx,v 1.9 2003/10/07 14:03:03 rdm Exp $
+// @(#)root/srputils:$Name:  $:$Id: SRPAuth.cxx,v 1.10 2003/10/07 21:09:55 rdm Exp $
 // Author: Fons Rademakers   15/02/2000
 
 /*************************************************************************
@@ -182,13 +182,6 @@ Int_t SRPAuthenticate(TAuthenticate *auth, const char *user, const char *passwd,
 
    if (version > 1) {
 
-     // Save passwd for later use ...
-     TAuthenticate::SetGlobalUser(user);
-     TAuthenticate::SetGlobalPasswd(psswd);
-     TAuthenticate::SetGlobalPwHash(kFALSE);
-     TAuthenticate::SetGlobalSRPPwd(kTRUE);
-
-
      // Receive result of the overall process
      sock->Recv(stat, kind);
      if (kind == kROOTD_ERR) {
@@ -196,10 +189,18 @@ Int_t SRPAuthenticate(TAuthenticate *auth, const char *user, const char *passwd,
        goto out;
      }
 
+     // Save passwd for later use ...
+     TAuthenticate::SetGlobalUser(user);
+     TAuthenticate::SetGlobalPasswd(psswd);
+     TAuthenticate::SetGlobalPwHash(kFALSE);
+     TAuthenticate::SetGlobalSRPPwd(kTRUE);
+
      if (ReUse == 1) {
 
        if (kind != kROOTD_RSAKEY)
-       Warning("SRPAuthenticate", "problems recvn RSA key flag: got message %d, flag: %d",kind,gRSAKey);
+       Warning("SRPAuthenticate",
+               "problems recvn RSA key flag: got message %d, flag: %d",
+                kind,gRSAKey);
        gRSAKey = 1;
 
        // Send the key securely
diff --git a/tutorials/TestAuth.C b/tutorials/TestAuth.C
index a15bf5deedc..cfb9a312902 100644
--- a/tutorials/TestAuth.C
+++ b/tutorials/TestAuth.C
@@ -1,19 +1,21 @@
-//////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////
 //
 //  Macro test authentication methods stand alone
 //
-//  NB: Kerberos cannot be tested in standalone
-//
+//  See $ROOTSYS/README/README.AUTH for additional details
 //
 //   Syntax:
 //
-//  .x TestAuth.C("<user>","<write path>",<port>,"<globus_det>")
+//  .x TestAuth.C(<port>,"<user>","<krb5_princ","<globus_det>")
 //
+//     <port>          = rootd port (default 1094)
 //     <user>          = login user name for the test
 //                      (default from getpwuid)
-//     <write path>    = path writable by <user>
-//                      (default /tmp)
-//     <port>          = rootd port (default 1094)
+//     <krb5_princ>    = Principal to be used for Krb5 authentication
+//                       in the form user@THE.REA.LM
+//                       ( default: <running_user@Default_Realm with
+//                                  Default_realm taken from /etc/krb5.conf
+//                                  or the $KRB5_CONFIG file )
 //     <globus_det>    = details for the globus authentication
 //                       ( default: ad:certificates cd:$HOME/.globus
 //                                  cf:usercert.pem kf:userkey.pem )
@@ -22,84 +24,87 @@
 //
 //  Example of successful output:
 //
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//    +                                                                   +
-//    +                         TestAuth.C                                +
-//    +                                                                   +
-//    +                Test of authentication methods                     +
-//    +                                                                   +
-//    +   Syntax:                                                         +
-//    +                                                                   +
-//    + .x TestAuth.C("<user>","<write path>",<port>,"<globus_det>")      +
-//    +                                                                   +
-//    +     <user>          = login user name for the test                +
-//    +                      (default from getpwuid)                      +
-//    +     <write path>    = path writable by <user>                     +
-//    +                      (default /tmp)                               +
-//    +     <port>          = rootd port (default 1094)                   +
-//    +     <globus_det>    = details for the globus authentication       +
-//    +                      ( default ad:certificates cd:$HOME/.globus   +
-//    +                                cf:usercert.pem kf:userkey.pem )   +
-//    +                                                                   +
-//    +           >>> MAKE SURE that rootd is running <<<                 +
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +                                                                             +
+//      +                         TestAuth.C                                          +
+//      +                                                                             +
+//      +                Test of authentication methods                               +
+//      +                                                                             +
+//      +   Syntax:                                                                   +
+//      +                                                                             +
+//      + .x TestAuth.C(<port>,"<user>","<krb5_princ>","<globus_det>")                +
+//      +                                                                             +
+//      +     <port>          = rootd port (default 1094)                             +
+//      +     <user>          = login user name for the test                          +
+//      +                      (default from getpwuid)                                +
+//      +     <krb5_princ>    = Principal to be used for Krb5 authentication          +
+//      +                       in the form user@THE.REA.LM                           +
+//      +                      ( default: <running_user@Default_Realm with            +
+//      +                                 Default_realm taken from /etc/krb5.conf     +
+//      +                                 or the $KRB5_CONFIG file )                  +
+//      +     <globus_det>    = details for the globus authentication                 +
+//      +                      ( default ad:certificates cd:$HOME/.globus             +
+//      +                                cf:usercert.pem kf:userkey.pem )             +
+//      +                                                                             +
+//      +                 >>> MAKE SURE that rootd is running <<<                     +
+//      +                                                                             +
+//      +             See $ROOTSYS/README/README.AUTH for additional details          +
+//      +                                                                             +
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 //
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//    +                                                         +
-//    +   Basic test parameters:                                +
-//    +                                                         +
-//    +   Local User is          : ganis
-//    +   Authentication Details : pt:0 ru:1 us:ganis
-//    +   Current directory is   : /afs/cern.ch/aleph/scratch/ganis/root/Linux.Standard/tutorials
-//    +   Test File              : /tmp/TestFile.root
-//    +   TFile::Open string     : root://localhost:5000//tmp/TestFile.root
-//    +                                                         +
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//    +                                                         +
-//    +   Testing UsrPwd ...                                    +
-// qwerty@localhost password:
-//    +                                                         +
-//    +   Testing SRP ...                                       +
-// qwerty@localhost SRP password:
-//    +                                                         +
-//    +   Testing Krb5 ...                                      +
-//    +   Krb5 authentication cannot be tested in standalone    +
-//    +                                                         +
-//    +   Testing Globus ...                                    +
-// Local Globus Certificates (    )
-// Enter <key>:<new value> to change:
-// Your identity: /O=Grid/OU=GlobusTest/OU=simpleCA-arthux.cern.ch/OU=cern.ch/CN=ganis
-// Enter GRID pass phrase for this identity:
-// Creating proxy ............................ Done
-// Your proxy is valid until: Sat Oct 18 14:23:00 2003
-//    +                                                         +
-//    +   Testing SSH ...                                       +
-// qwerty@localhost's password:
-//    +                                                         +
-//    +   Testing UidGid ...                                    +
-//    +                                                         +
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +                                                                             +
+//      +   Basic test parameters:                                                    +
+//      +                                                                             +
+//      +   Local User is          : ganis
+//      +   Authentication Details : pt:0 ru:1 us:ganis
+//      +   Current directory is   : /home/ganis/local/root/root/tutorials
+//      +   TFTP string            : root://localhost:1094
+//      +   Krb5 Details           : pt:0 ru:1 us:ganis@PCEPSFT43.CERN.CH
+//      +                                                                             +
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +                                                                             +
+//      +   Testing UsrPwd ...                                                        +
+//   ganis@localhost password:
+//      +                                                                             +
+//      +   Testing SRP ...                                                           +
+//   ganis@localhost SRP password:
+//      +                                                                             +
+//      +   Testing Krb5 ...                                                          +
+//   Password for ganis@PCEPSFT43.CERN.CH:
+//      +                                                                             +
+//      +   Testing Globus ...                                                        +
+//    Local Globus Certificates (    )
+//    Enter <key>:<new value> to change:
+//   Your identity: /O=Grid/OU=GlobusTest/OU=simpleCA-arthux.cern.ch/OU=cern.ch/CN=ganis
+//   Enter GRID pass phrase for this identity:
+//   Creating proxy ............................ Done
+//   Your proxy is valid until: Fri Oct 31 09:33:04 2003
+//      +                                                                             +
+//      +   Testing SSH ...                                                           +
+//   ganis@localhost's password:
+//      +                                                                             +
+//      +   Testing UidGid ...                                                        +
+//      +                                                                             +
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 //
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//    +                                                         +
-//    +   Result of the tests:                                  +
-//    +                                                         +
-//    +   Method: 0 (UsrPwd): successful! (reuse: successful!)  +
-//    +   Method: 1    (SRP): successful! (reuse: successful!)  +
-//    +   Method: 3 (Globus): successful! (reuse: successful!)  +
-//    +   Method: 4    (SSH): successful! (reuse: successful!)  +
-//    +   Method: 5 (UidGid): successful!                       +
-//    +                                                         +
-//    +   Could not be tested:                                  +
-//    +                                                         +
-//    +   Method: 2   (Krb5): not testable                      +
-//    +                                                         +
-//    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//      +                                                                             +
+//      +   Result of the tests:                                                      +
+//      +                                                                             +
+//      +   Method: 0 (UsrPwd): successful! (reuse: successful!)                      +
+//      +   Method: 1    (SRP): successful! (reuse: successful!)                      +
+//      +   Method: 2   (Krb5): successful! (reuse: successful!)                      +
+//      +   Method: 3 (Globus): successful! (reuse: successful!)                      +
+//      +   Method: 4    (SSH): successful! (reuse: successful!)                      +
+//      +   Method: 5 (UidGid): successful!                                           +
+//      +                                                                             +
+//      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 //
-///////////////////////////////////////////////////////////////////////
 //
-int TestAuth(char *user = "", char *workdir = "/tmp",
-             int port = 1094, char *globus  = "")
+///////////////////////////////////////////////////////////////////////////////////////
+//
+int TestAuth(int port = 1094, char *user = "", char *krb5  = "", char *globus  = "")
 {
    //
    // This macro tests the authentication methods
@@ -109,63 +114,40 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
 // Getting debug flag
    Int_t lDebug = gEnv->GetValue("Root.Debug",0);
 
-// Setting test flag
-   gEnv->SetValue("Test.Auth",1);
-
 // Useful flags
    Bool_t HaveMeth[6] = {1,0,0,0,0,1};
    Int_t  TestMeth[6] = {0,0,0,0,0,0};
    Int_t TestReUse[6] = {3,3,3,3,3,3};
 
-// Testing availibilities
-   char *p;
-
-//   TString HaveSRP = "@srpdir@";
-   if ((p = gSystem->DynamicPathName("libSRPAuth", kTRUE))) {
-      HaveMeth[1] = 1;
-   }
-   delete[] p;
-
-// Check if Kerberos is available
-   if ((p = gSystem->DynamicPathName("libKrb5Auth", kTRUE))) {
-      HaveMeth[2] = 1;
-   }
-   delete[] p;
-
-// Check if Globus is available
-   if ((p = gSystem->DynamicPathName("libGlobusAuth", kTRUE))) {
-      HaveMeth[3] = 1;
-   }
-   delete[] p;
-
-// Check if SSH available
-   if (gSystem->Which(gSystem->Getenv("PATH"), "ssh", kExecutePermission)) {
-      HaveMeth[4] = 1;
-   }
 
 // Some Printout
-   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-   printf("   +                                                                   +\n");
-   printf("   +                         TestAuth.C                                +\n");
-   printf("   +                                                                   +\n");
-   printf("   +                Test of authentication methods                     +\n");
-   printf("   +                                                                   +\n");
-   printf("   +   Syntax:                                                         +\n");
-   printf("   +                                                                   +\n");
-   printf("   + .x TestAuth.C(\"<user>\",\"<write path>\",<port>,\"<globus_det>\")      +\n");
-   printf("   +                                                                   +\n");
-   printf("   +     <user>          = login user name for the test                +\n");
-   printf("   +                      (default from getpwuid)                      +\n");
-   printf("   +     <write path>    = path writable by <user>                     +\n");
-   printf("   +                      (default /tmp)                               +\n");
-   printf("   +     <port>          = rootd port (default 1094)                   +\n");
-   printf("   +     <globus_det>    = details for the globus authentication       +\n");
-   printf("   +                      ( default ad:certificates cd:$HOME/.globus   +\n");
-   printf("   +                                cf:usercert.pem kf:userkey.pem )   +\n");
-   printf("   +                                                                   +\n");
-   printf("   +           >>> MAKE SURE that rootd is running <<<                 +\n");
-   printf("   +                                                                   +\n");
-   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
+   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+   printf("   +                                                                             +\n");
+   printf("   +                         TestAuth.C                                          +\n");
+   printf("   +                                                                             +\n");
+   printf("   +                Test of authentication methods                               +\n");
+   printf("   +                                                                             +\n");
+   printf("   +   Syntax:                                                                   +\n");
+   printf("   +                                                                             +\n");
+   printf("   + .x TestAuth.C(<port>,\"<user>\",\"<krb5_princ>\",\"<globus_det>\")                +\n");
+   printf("   +                                                                             +\n");
+   printf("   +     <port>          = rootd port (default 1094)                             +\n");
+   printf("   +     <user>          = login user name for the test                          +\n");
+   printf("   +                      (default from getpwuid)                                +\n");
+   printf("   +     <krb5_princ>    = Principal to be used for Krb5 authentication          +\n");
+   printf("   +                       in the form user@THE.REA.LM                           +\n");
+   printf("   +                      ( default: <running_user@Default_Realm with            +\n");
+   printf("   +                                 Default_realm taken from /etc/krb5.conf     +\n");
+   printf("   +                                 or the $KRB5_CONFIG file )                  +\n");
+   printf("   +     <globus_det>    = details for the globus authentication                 +\n");
+   printf("   +                      ( default ad:certificates cd:$HOME/.globus             +\n");
+   printf("   +                                cf:usercert.pem kf:userkey.pem )             +\n");
+   printf("   +                                                                             +\n");
+   printf("   +                     >>> MAKE SURE that rootd is running <<<                 +\n");
+   printf("   +                                                                             +\n");
+   printf("   +             See $ROOTSYS/README/README.AUTH for additional details          +\n");
+   printf("   +                                                                             +\n");
+   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
 
 // Useful variables
 
@@ -190,72 +172,109 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
 
    }
 
-// Working Dir
-   TString WorkDir = workdir;
-   if (WorkDir == "" ||
-       gSystem->AccessPathName(WorkDir, kWritePermission)) {
-       if (lDebug > 0)
-          printf(">>>> Path: %s not writable!\n",WorkDir.Data());
-       WorkDir = "/tmp";
-       if (gSystem->AccessPathName(WorkDir, kWritePermission)) {
-          if (lDebug > 0)
-             printf(">>>> Path: %s not writable!\n",WorkDir.Data());
-          WorkDir = gSystem->WorkingDirectory();
-          if (WorkDir == "" ||
-             gSystem->AccessPathName(WorkDir, kWritePermission)) {
-             if (lDebug > 0)
-                printf(">>>> Path: %s not writable!\n",WorkDir.Data());
-             printf("unable to find writable dir for temporary test file: return!\n");
-             return 1;
-	  }
-       }
-   }
-
-// TempFile path
-   TString FileTemp = WorkDir + "/TestFile.root";
-
-// Create test file first
-   TFile *TestFile = new TFile(FileTemp.Data(),"RECREATE");
-   if (TestFile && TestFile->IsOpen()) {
-     Real_t theVector[5] = {0.,1.,2.,3.,4.};
-     TVector vc(5,theVector);
-     vc.Write();
-     if (lDebug > 1)
-        TestFile->ls();
-     if (TestFile) delete TestFile;
-   } else {
-     printf("Cannot open test file: return!\n");
-     return 1;
-   }
-
-// File path string for TFile::Open
-   TString WkgFile =
-      TString("root://localhost:") + port + "/" + WorkDir + "/TestFile.root";
-
 // Host
    TString Host = "localhost";
+   TString HostName = gSystem->HostName();
+
+// File path string for TFTP
+   //TString TFTPPath = TString("root://localhost:")+ port ;
+   TString TFTPPath = TString("root://")+User+TString("@localhost:")+ port ;
+   //TString TFTPPathKrb5 = TString("root://") + HostName + TString(":")+ port ;
+   TString TFTPPathKrb5 = TString("root://") + User+ TString("@") +
+                          HostName + TString(":")+ port ;
 
 // Details
    TString Details = TString("pt:0 ru:1 us:") + User;
-   TString GlobusDetails = TString("pt:0 ru:1 ") + TString(globus);
+
+// Testing availibilities
+   char *p;
+
+//   TString HaveSRP = "@srpdir@";
+   if ((p = gSystem->DynamicPathName("libSRPAuth", kTRUE))) {
+      HaveMeth[1] = 1;
+   }
+   delete[] p;
+
+// Check if Kerberos is available
+   TString Krb5Details;
+   TString Krb5Open;
+   if ((p = gSystem->DynamicPathName("libKrb5Auth", kTRUE))) {
+      HaveMeth[2] = 1;
+      // Special details string for Kerberos
+      if (strlen(krb5) > 0) {
+         Krb5Details = TString("pt:0 ru:1 us:") + TString(krb5);
+      } else {
+         // Must determine a default ... look in config file
+         TString Krb5Conf, Realm;
+         if (gSystem->Getenv("KRB5_CONFIG")) {
+            if (!gSystem->AccessPathName(gSystem->Getenv("KRB5_CONFIG"), kReadPermission)) {
+               Krb5Conf = gSystem->Getenv("KRB5_CONFIG");
+            }
+         } else if (!gSystem->AccessPathName("/etc/krb5.conf", kReadPermission)) {
+            Krb5Conf = "/etc/krb5.conf";
+         } else {
+            printf("\n >>>> Kerberos Principal undefined\n");
+            printf("\n >>>> unable to localize Kerberos config file to build a default\n");
+            printf("\n >>>> Switching off Kerberos\n");
+            printf("\n >>>> Run again with giving the principal as 3rd argument\n");
+            printf("\n >>>> or define the variable KRB5_CONFIG with the full path \n");
+            printf("\n >>>> to the config file (usually /etc/krb5.conf)\n");
+            HaveMeth[2] = 0;
+         }
+         if (HaveMeth[2] == 1) {
+            FILE *fc = fopen(Krb5Conf.Data(),"r");
+            if (fc) {
+               char line[1024], fs1[1024], fs2[1024], fs3[1024];
+               while (fgets(line, sizeof(line), fc) != 0) {
+                  int nf = sscanf(line,"%s %s %s",fs1,fs2,fs3);
+                  if (nf == 3 && !strcmp(fs1,"default_realm")) {
+                     Realm = fs3;
+                     break;
+                  }
+               }
+               Krb5Details = TString("pt:0 ru:1 us:") + User + TString("@") + Realm;
+               fclose(fc);
+            } else {
+               HaveMeth[2] = 0;
+            }
+         }
+      }
+   }
+   delete[] p;
+
+// Check if Globus is available
+   TString GlobusDetails;
+   if ((p = gSystem->DynamicPathName("libGlobusAuth", kTRUE))) {
+      HaveMeth[3] = 1;
+      // Special details string for Globus
+      GlobusDetails = TString("pt:0 ru:1 ") + TString(globus);
+   }
+   delete[] p;
+
+// Check if SSH available
+   if (gSystem->Which(gSystem->Getenv("PATH"), "ssh", kExecutePermission)) {
+      HaveMeth[4] = 1;
+   }
 
 // Test parameter Printout
-   printf("\n   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-   printf("   +                                                         +\n");
-   printf("   +   Basic test parameters:                                +\n");
-   printf("   +                                                         +\n");
+   printf("\n   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+   printf("   +                                                                             +\n");
+   printf("   +   Basic test parameters:                                                    +\n");
+   printf("   +                                                                             +\n");
    printf("   +   Local User is          : %s \n",User.Data());
    printf("   +   Authentication Details : %s \n",Details.Data());
    printf("   +   Current directory is   : %s \n",gSystem->WorkingDirectory());
-   printf("   +   Test File              : %s \n",FileTemp.Data());
-   printf("   +   TFile::Open string     : %s \n",WkgFile.Data());
-   printf("   +                                                         +\n");
-   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+   printf("   +   TFTP string            : %s \n",TFTPPath.Data());
+   if (HaveMeth[2]) {
+      printf("   +   Krb5 Details           : %s \n",Krb5Details.Data());
+   }
+   printf("   +                                                                             +\n");
+   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
 
 
 // UsrPwd method
-   printf("   +                                                         +\n");
-   printf("   +   Testing UsrPwd ...                                    +\n");
+   printf("   +                                                                             +\n");
+   printf("   +   Testing UsrPwd ...                                                        +\n");
 
    // Create a THostAuth instantiation for the local host
    THostAuth *hawk = new THostAuth(Host.Data(),User.Data(),0,Details.Data());
@@ -267,17 +286,14 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
    if (lDebug > 0)
       hawk->Print();
 
+   {
    // First authentication attempt
-   TFile *f1 = TFile::Open(WkgFile.Data(),"read");
-   if (f1 && f1->IsOpen()) {
+   TFTP t1(TFTPPath.Data());
+   if (t1.IsOpen()) {
       TestMeth[0] = 1;
-      if (lDebug > 1)
-         f1->ls();
    } else {
       printf(" >>>>>>>>>>>>>>>> Test of UsrPwd authentication failed \n");
-   }
-   // Delete file
-   if (f1) delete f1;
+   }}
 
    // Get pointer to relevant HostAuth
    THostAuth *ha = TAuthenticate::GetHostAuth(Host.Data(),User.Data());
@@ -301,8 +317,8 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
 
 // SRP method
    if ( HaveMeth[1] ) {
-      printf("   +                                                         +\n");
-      printf("   +   Testing SRP ...                                       +\n");
+      printf("   +                                                                             +\n");
+      printf("   +   Testing SRP ...                                                           +\n");
 
      // Add relevant info to HostAuth
       ha->SetFirst(1,Details.Data());
@@ -310,16 +326,12 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
          ha->Print();
 
      // Authentication attempt
-      TFile *f1 = TFile::Open(WkgFile.Data(),"read");
-      if (f1 && f1->IsOpen()) {
+      TFTP t1(TFTPPath.Data());
+      if (t1.IsOpen()) {
          TestMeth[1] = 1;
-         if (lDebug > 1)
-            f1->ls();
       } else {
          printf(" >>>>>>>>>>>>>>>> Test of SRP authentication failed \n");
       }
-       // Delete file
-      if (f1) delete f1;
 
       // Try ReUse
       if (TestMeth[1] == 1) {
@@ -342,19 +354,51 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
 
 // Kerberos method
    if ( HaveMeth[2] ) {
-      printf("   +                                                         +\n");
-      printf("   +   Testing Krb5 ...                                      +\n");
+      printf("   +                                                                             +\n");
+      printf("   +   Testing Krb5 ...                                                          +\n");
+
+      // Create a special THostAuth instantiation for kerberos
+      THostAuth *hak = new THostAuth(HostName.Data(),User.Data(),2,Krb5Details.Data());
+
+      // Add object to list
+      TAuthenticate::GetAuthInfo()->Add(hak);
+      if (lDebug > 0)
+         hak->Print();
+
+     // Authentication attempt
+      TFTP t1(TFTPPathKrb5.Data());
+      if (t1.IsOpen()) {
+         TestMeth[2] = 1;
+      } else {
+         printf(" >>>>>>>>>>>>>>>> Test of Kerberos authentication failed \n");
+         if (strlen(krb5) > 0) {
+            printf(" >>>>>>>>>>>>>>>> details used: '%s' \n",krb5);
+         }
+      }
 
-      // Standalone test not possible
-      TestMeth[2] = 2;
-      printf("   +   Krb5 authentication cannot be tested in standalone    +\n");
+      // Try ReUse
+      if (TestMeth[2] == 1) {
+         TIter next(hak->Established());
+         TAuthDetails *ai;
+         while ((ai = (TAuthDetails *) next())) {
+            if (ai->GetMethod() == 2) {
+               Int_t OffSet = ai->GetOffSet();
+               TestReUse[2] = 0;
+               if (OffSet > -1) {
+                  TestReUse[2] = 1;
+               }
+            }
+         }
+      }
+      // remove method from available list
+      hak->RemoveMethod(2);
    }
 
 
 // Globus method
    if ( HaveMeth[3] ) {
-      printf("   +                                                         +\n");
-      printf("   +   Testing Globus ...                                    +\n");
+      printf("   +                                                                             +\n");
+      printf("   +   Testing Globus ...                                                        +\n");
 
      // Add relevant info to HostAuth
       ha->SetFirst(3,GlobusDetails.Data());
@@ -362,11 +406,9 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
          ha->Print();
 
      // Authentication attempt
-      TFile *f1 = TFile::Open(WkgFile.Data(),"read");
-      if (f1 && f1->IsOpen()) {
+      TFTP t1(TFTPPath.Data());
+      if (t1.IsOpen()) {
          TestMeth[3] = 1;
-         if (lDebug > 1)
-            f1->ls();
       } else {
          printf(" >>>>>>>>>>>>>>>> Test of Globus authentication failed \n");
          if (strlen(globus) > 0) {
@@ -382,18 +424,16 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
                printf(" >>>>>>>>>>>>>>>> You are not root,");
                printf(" you may not have the right privileges\n");
                printf(" >>>>>>>>>>>>>>>> Make sure that the used details are correct! \n");
-	    }
+            }
          }
       }
-       // Delete file
-      if (f1) delete f1;
 
       // Try ReUse
       if (TestMeth[3] == 1) {
          TIter next(ha->Established());
          TAuthDetails *ai;
          while ((ai = (TAuthDetails *) next())) {
-            if (ai->GetMethod() == 1) {
+            if (ai->GetMethod() == 3) {
                Int_t OffSet = ai->GetOffSet();
                TestReUse[3] = 0;
                if (OffSet > -1) {
@@ -409,8 +449,8 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
 // SSH methodg
 
    if ( HaveMeth[4] ) {
-      printf("   +                                                         +\n");
-      printf("   +   Testing SSH ...                                       +\n");
+      printf("   +                                                                             +\n");
+      printf("   +   Testing SSH ...                                                           +\n");
 
      // Add relevant info to HostAuth
       ha->SetFirst(4,Details.Data());
@@ -418,16 +458,12 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
          ha->Print();
 
      // Authentication attempt
-      TFile *f1 = TFile::Open(WkgFile.Data(),"read");
-      if (f1 && f1->IsOpen()) {
+      TFTP t1(TFTPPath.Data());
+      if (t1.IsOpen()) {
          TestMeth[4] = 1;
-         if (lDebug > 0)
-            f1->ls();
       } else {
          printf(" >>>>>>>>>>>>>>>> Test of SSH authentication failed \n");
       }
-       // Delete file
-      if (f1) delete f1;
 
       // Try ReUse
       if (TestMeth[4] == 1) {
@@ -449,8 +485,8 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
 
 
 // Rfio method
-   printf("   +                                                         +\n");
-   printf("   +   Testing UidGid ...                                    +\n");
+   printf("   +                                                                             +\n");
+   printf("   +   Testing UidGid ...                                                        +\n");
 
    // Add relevant info to HostAuth
    ha->SetFirst(5,Details.Data());
@@ -458,22 +494,19 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
       ha->Print();
 
    // Authentication attempt
-   TFile *f1 = TFile::Open(WkgFile.Data(),"read");
-   if (f1 && f1->IsOpen()) {
+   {
+   TFTP t1(TFTPPath.Data());
+   if (t1.IsOpen()) {
       TestMeth[5] = 1;
-      if (lDebug > 1)
-         f1->ls();
    } else {
       printf(" >>>>>>>>>>>>>>>> Test of UidGid authentication failed \n");
-   }
-   // Delete file
-   if (f1) delete f1;
+   }}
 
    // remove method from available list
    ha->RemoveMethod(5);
 
-   printf("   +                                                         +\n");
-   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+   printf("   +                                                                             +\n");
+   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
 
    // Print available host auth info
    if (lDebug > 0)
@@ -486,35 +519,39 @@ int TestAuth(char *user = "", char *workdir = "/tmp",
    gEnv->SetValue("Test.Auth",0);
 
 // Final Printout
-   printf("\n   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-   printf("   +                                                         +\n");
-   printf("   +   Result of the tests:                                  +\n");
-   printf("   +                                                         +\n");
+   printf("\n   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+   printf("   +                                                                             +\n");
+   printf("   +   Result of the tests:                                                      +\n");
+   printf("   +                                                                             +\n");
    char status[4][20] = {"failed!","successful!","not testable","not tested"};
    int i = 0;
    for( i=0; i<6; i++ ) {
      if (HaveMeth[i] && TestMeth[i] < 2) {
        if (i < 5) {
-          printf("   +   Method: %d %8s: %11s (reuse: %11s)  +\n",i,
+          printf("   +   Method: %d %8s: %11s (reuse: %11s)                      +\n",i,
                          Form("(%s)",TAuthenticate::GetAuthMethod(i)),
                          status[TestMeth[i]],status[TestReUse[i]]);
        } else
-          printf("   +   Method: %d %8s: %11s                       +\n",i,
+          printf("   +   Method: %d %8s: %11s                                           +\n",i,
                          Form("(%s)",TAuthenticate::GetAuthMethod(i)),
                          status[TestMeth[i]]);
      }
    }
-   printf("   +                                                         +\n");
-   printf("   +   Could not be tested:                                  +\n");
-   printf("   +                                                         +\n");
+   Bool_t NotPrinted = kTRUE;
    for( i=0; i<6; i++ ) {
      if (HaveMeth[i] && TestMeth[i] > 1) {
-	printf("   +   Method: %d %8s: %11s                      +\n",i,
+        if (NotPrinted) {
+           printf("   +                                                                             +\n");
+           printf("   +   Could not be tested:                                                      +\n");
+           printf("   +                                                                             +\n");
+           NotPrinted = kFALSE;
+        }
+        printf("   +   Method: %d %8s: %11s                      +\n",i,
                        Form("(%s)",TAuthenticate::GetAuthMethod(i)),
                        status[TestMeth[i]]);
      }
    }
-   printf("   +                                                         +\n");
-   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+   printf("   +                                                                             +\n");
+   printf("   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
 
 }
-- 
GitLab