Whamcloud - gitweb
branch: HEAD
[fs/lustre-release.git] / lustre / utils / gss / nfs-utils-1.0.10-lustre.diff
index a9d31e0..58f21fe 100644 (file)
@@ -1,6 +1,6 @@
-diff -rup nfs-utils-1.0.10.orig/configure.in nfs-utils-1.0.10/configure.in
---- nfs-utils-1.0.10.orig/configure.in 2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/configure.in      2006-12-15 15:11:52.000000000 -0700
+diff -rNup nfs-utils-1.0.10/configure.in nfs-utils-1.0.10.lustre/configure.in
+--- nfs-utils-1.0.10/configure.in      2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/configure.in       2007-05-15 13:00:53.000000000 -0600
 @@ -17,61 +17,14 @@ AC_ARG_WITH(release,
        RELEASE=$withval,
        RELEASE=1)
@@ -189,9 +189,9 @@ diff -rup nfs-utils-1.0.10.orig/configure.in nfs-utils-1.0.10/configure.in
 +      utils/gssd/Makefile])
  AC_OUTPUT
  
-diff -rup nfs-utils-1.0.10.orig/Makefile.am nfs-utils-1.0.10/Makefile.am
---- nfs-utils-1.0.10.orig/Makefile.am  2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/Makefile.am       2006-12-15 15:11:52.000000000 -0700
+diff -rNup nfs-utils-1.0.10/Makefile.am nfs-utils-1.0.10.lustre/Makefile.am
+--- nfs-utils-1.0.10/Makefile.am       2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/Makefile.am        2007-05-15 13:00:53.000000000 -0600
 @@ -1,6 +1,6 @@
  ## Process this file with automake to produce Makefile.in
  
@@ -200,9 +200,9 @@ diff -rup nfs-utils-1.0.10.orig/Makefile.am nfs-utils-1.0.10/Makefile.am
  
  MAINTAINERCLEANFILES = Makefile.in
  
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/cacheio.c nfs-utils-1.0.10/utils/gssd/cacheio.c
---- nfs-utils-1.0.10.orig/utils/gssd/cacheio.c 2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/cacheio.c      2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/cacheio.c nfs-utils-1.0.10.lustre/utils/gssd/cacheio.c
+--- nfs-utils-1.0.10/utils/gssd/cacheio.c      2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/cacheio.c       2007-05-15 13:01:35.000000000 -0600
 @@ -227,7 +227,8 @@ int qword_get(char **bpp, char *dest, in
                return -1;
        while (*bp == ' ') bp++;
@@ -213,9 +213,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/cacheio.c nfs-utils-1.0.10/utils/gssd
        return len;
  }
  
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/context.c nfs-utils-1.0.10/utils/gssd/context.c
---- nfs-utils-1.0.10.orig/utils/gssd/context.c 2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/context.c      2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/context.c nfs-utils-1.0.10.lustre/utils/gssd/context.c
+--- nfs-utils-1.0.10/utils/gssd/context.c      2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/context.c       2007-05-15 13:01:35.000000000 -0600
 @@ -33,8 +33,6 @@
  #include <syslog.h>
  #include <string.h>
@@ -225,9 +225,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/context.c nfs-utils-1.0.10/utils/gssd
  #include "gss_util.h"
  #include "gss_oids.h"
  #include "err_util.h"
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/context.h nfs-utils-1.0.10/utils/gssd/context.h
---- nfs-utils-1.0.10.orig/utils/gssd/context.h 2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/context.h      2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/context.h nfs-utils-1.0.10.lustre/utils/gssd/context.h
+--- nfs-utils-1.0.10/utils/gssd/context.h      2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/context.h       2007-05-15 13:01:35.000000000 -0600
 @@ -31,8 +31,6 @@
  #ifndef _CONTEXT_H_
  #define _CONTEXT_H_
@@ -237,9 +237,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/context.h nfs-utils-1.0.10/utils/gssd
  /* Hopefully big enough to hold any serialized context */
  #define MAX_CTX_LEN 4096
  
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/context_lucid.c nfs-utils-1.0.10/utils/gssd/context_lucid.c
---- nfs-utils-1.0.10.orig/utils/gssd/context_lucid.c   2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/context_lucid.c        2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/context_lucid.c nfs-utils-1.0.10.lustre/utils/gssd/context_lucid.c
+--- nfs-utils-1.0.10/utils/gssd/context_lucid.c        2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/context_lucid.c 2007-05-15 13:01:35.000000000 -0600
 @@ -41,11 +41,7 @@
  #include <syslog.h>
  #include <string.h>
@@ -344,9 +344,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/context_lucid.c nfs-utils-1.0.10/util
  
                /* derive and send down: Ke, Ki, and Kc */
  
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/context_mit.c nfs-utils-1.0.10/utils/gssd/context_mit.c
---- nfs-utils-1.0.10.orig/utils/gssd/context_mit.c     2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/context_mit.c  2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/context_mit.c nfs-utils-1.0.10.lustre/utils/gssd/context_mit.c
+--- nfs-utils-1.0.10/utils/gssd/context_mit.c  2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/context_mit.c   2007-05-15 13:01:35.000000000 -0600
 @@ -39,7 +39,6 @@
  #include <errno.h>
  #include <gssapi/gssapi.h>
@@ -369,9 +369,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/context_mit.c nfs-utils-1.0.10/utils/
                if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
  
                /* Only applicable flag for this is initiator */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/context_spkm3.c nfs-utils-1.0.10/utils/gssd/context_spkm3.c
---- nfs-utils-1.0.10.orig/utils/gssd/context_spkm3.c   2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/context_spkm3.c        2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/context_spkm3.c nfs-utils-1.0.10.lustre/utils/gssd/context_spkm3.c
+--- nfs-utils-1.0.10/utils/gssd/context_spkm3.c        2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/context_spkm3.c 2007-05-15 13:01:35.000000000 -0600
 @@ -33,8 +33,6 @@
  #include <syslog.h>
  #include <string.h>
@@ -381,9 +381,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/context_spkm3.c nfs-utils-1.0.10/util
  #include "gss_util.h"
  #include "gss_oids.h"
  #include "err_util.h"
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/err_util.c nfs-utils-1.0.10/utils/gssd/err_util.c
---- nfs-utils-1.0.10.orig/utils/gssd/err_util.c        2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/err_util.c     2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/err_util.c nfs-utils-1.0.10.lustre/utils/gssd/err_util.c
+--- nfs-utils-1.0.10/utils/gssd/err_util.c     2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/err_util.c      2007-05-15 13:01:35.000000000 -0600
 @@ -32,6 +32,8 @@
  #include <stdarg.h>
  #include <syslog.h>
@@ -434,9 +434,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/err_util.c nfs-utils-1.0.10/utils/gss
 +      }
 +}
 +
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/err_util.h nfs-utils-1.0.10/utils/gssd/err_util.h
---- nfs-utils-1.0.10.orig/utils/gssd/err_util.h        2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/err_util.h     2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/err_util.h nfs-utils-1.0.10.lustre/utils/gssd/err_util.h
+--- nfs-utils-1.0.10/utils/gssd/err_util.h     2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/err_util.h      2007-05-15 13:01:35.000000000 -0600
 @@ -33,5 +33,6 @@
  
  void initerr(char *progname, int verbosity, int fg);
@@ -444,9 +444,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/err_util.h nfs-utils-1.0.10/utils/gss
 +void print_hexl(int pri, unsigned char *cp, int length);
  
  #endif /* _ERR_UTIL_H_ */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gss_clnt_send_err.c nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c
---- nfs-utils-1.0.10.orig/utils/gssd/gss_clnt_send_err.c       2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c    2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c nfs-utils-1.0.10.lustre/utils/gssd/gss_clnt_send_err.c
+--- nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c    2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gss_clnt_send_err.c     2007-05-15 13:00:53.000000000 -0600
 @@ -47,6 +47,7 @@
  #include "gssd.h"
  #include "write_bytes.h"
@@ -460,9 +460,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gss_clnt_send_err.c nfs-utils-1.0.10/
        exit(0);
  }
 +#endif
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd.c nfs-utils-1.0.10/utils/gssd/gssd.c
---- nfs-utils-1.0.10.orig/utils/gssd/gssd.c    2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/gssd.c 2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gssd.c nfs-utils-1.0.10.lustre/utils/gssd/gssd.c
+--- nfs-utils-1.0.10/utils/gssd/gssd.c 2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gssd.c  2007-05-15 13:01:35.000000000 -0600
 @@ -38,9 +38,12 @@
  
  #include "config.h"
@@ -689,9 +689,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd.c nfs-utils-1.0.10/utils/gssd/gs
 +      printerr(0, "lgssd exiting\n");
 +      return 0;
  }
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd.h nfs-utils-1.0.10/utils/gssd/gssd.h
---- nfs-utils-1.0.10.orig/utils/gssd/gssd.h    2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/gssd.h 2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gssd.h nfs-utils-1.0.10.lustre/utils/gssd/gssd.h
+--- nfs-utils-1.0.10/utils/gssd/gssd.h 2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gssd.h  2007-05-15 13:01:35.000000000 -0600
 @@ -48,8 +48,13 @@
  #define GSSD_DEFAULT_CRED_PREFIX              "krb5cc_"
  #define GSSD_DEFAULT_MACHINE_CRED_SUFFIX      "machine"
@@ -747,9 +747,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd.h nfs-utils-1.0.10/utils/gssd/gs
 +void lgssd_mutex_put(int semid);
  
  #endif /* _RPC_GSSD_H_ */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_main_loop.c nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c
---- nfs-utils-1.0.10.orig/utils/gssd/gssd_main_loop.c  2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c       2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c nfs-utils-1.0.10.lustre/utils/gssd/gssd_main_loop.c
+--- nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c       2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gssd_main_loop.c        2007-05-15 13:01:35.000000000 -0600
 @@ -94,11 +94,13 @@ scan_poll_results(int ret)
  };
  
@@ -819,9 +819,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_main_loop.c nfs-utils-1.0.10/uti
        close(fd);
        return;
  }
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gssd/gssd_proc.c
---- nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c       2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/gssd_proc.c    2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gssd_proc.c nfs-utils-1.0.10.lustre/utils/gssd/gssd_proc.c
+--- nfs-utils-1.0.10/utils/gssd/gssd_proc.c    2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gssd_proc.c     2007-05-15 13:21:06.000000000 -0600
 @@ -43,7 +43,6 @@
  #endif
  #include "config.h"
@@ -1312,7 +1312,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
 +      printerr(2, "successfully refreshed lgd\n");
 +      return 0;
 +}
-+
 +static
 +int gssd_create_lgd(struct clnt_info *clp,
 +                  struct lustre_gss_data *lgd,
@@ -1360,7 +1360,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
 +              pgsserr(0, maj_stat, min_stat, lgd->lgd_mech);
 +              goto out_fail;
 +      }
++
 +      retval = gssd_refresh_lgd(lgd);
 +
 +      if (lgd->lgd_name != GSS_C_NO_NAME)
@@ -1415,7 +1415,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
  
  /*
   * this code uses the userland rpcsec gss library to create a krb5
-@@ -668,27 +910,78 @@ int create_auth_rpc_client(struct clnt_i
+@@ -668,103 +910,145 @@ int create_auth_rpc_client(struct clnt_i
  void
  handle_krb5_upcall(struct clnt_info *clp)
  {
@@ -1462,6 +1462,18 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
 +              return;
 +      }
 +
++      /* FIXME temporary fix, do this before fork.
++       * in case of errors could have memory leak!!!
++       */
++      if (updata.uid == 0) {
++              if (gssd_get_krb5_machine_cred_list(&credlist)) {
++                      printerr(0, "ERROR: Failed to obtain machine "
++                                  "credentials\n");
++                      do_error_downcall(clp->krb5_fd, updata.seq, -EPERM, 0);
++                      return;
++              }
++      }
++
 +      /* fork child process */
 +      pid = fork();
 +      if (pid < 0) {
@@ -1473,23 +1485,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
 +              return;
 +      }
 +
-+      printerr(1, "krb5 upcall: seq %u, uid %u, svc %u, nid 0x%llx, "
-+               "pag %llx, obd %s\n", updata.seq, updata.uid, updata.svc,
-+               updata.nid, updata.pag, updata.obd);
++      printerr(1, "krb5 upcall: seq %u, uid %u, svc %u, nid 0x%llx, obd %s\n",
++               updata.seq, updata.uid, updata.svc, updata.nid, updata.obd);
 +
-+      /* XXX in kernel pag is defined as "unsigned long", which might
-+       * not keep original signed value after converted to u64.
-+       */
-+      if (updata.pag != updata.uid &&
-+          ((updata.pag == 0xffffffffffffffffULL) ||
-+           (updata.pag == 0xffffffff))) {
-+              printerr(0, "uid %u: pag %llx not allowed\n",
-+                       updata.uid, updata.pag);
-+              lgd.lgd_rpc_err = -EPROTO;
-+              goto out_return_error;
-       }
--      if (uid == 0) {
 +      if (updata.svc != LUSTRE_GSS_SVC_MDS &&
 +          updata.svc != LUSTRE_GSS_SVC_OSS) {
 +              printerr(0, "invalid svc %d\n", updata.svc);
@@ -1501,15 +1499,17 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
 +      if (construct_service_name(clp, &updata)) {
 +              printerr(0, "failed to construct service name\n");
 +              goto out_return_error;
-+      }
-+
+       }
+-      if (uid == 0) {
 +      if (updata.uid == 0) {
                int success = 0;
  
                /*
-@@ -696,75 +989,66 @@ handle_krb5_upcall(struct clnt_info *clp
+                * Get a list of credential cache names and try each
                 * of them until one works or we've tried them all
                 */
++/*
                if (gssd_get_krb5_machine_cred_list(&credlist)) {
 -                      printerr(0, "WARNING: Failed to obtain machine "
 -                                  "credentials for connection to "
@@ -1519,6 +1519,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
 +                                  "credentials for %s\n", clp->servicename);
 +                      goto out_return_error;
                }
++*/
                for (ccname = credlist; ccname && *ccname; ccname++) {
                        gssd_setup_krb5_machine_gss_ccache(*ccname);
 -                      if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
@@ -1551,8 +1552,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
        else {
                /* Tell krb5 gss which credentials cache to use */
 -              gssd_setup_krb5_user_gss_ccache(uid, clp->servername);
-+              gssd_setup_krb5_user_gss_ccache(updata.pag, updata.uid,
-+                                              clp->servicename);
++              gssd_setup_krb5_user_gss_ccache(updata.uid, clp->servicename);
  
 -              if ((create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
 -                                                      AUTHTYPE_KRB5)) != 0) {
@@ -1623,9 +1623,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gssd_proc.c nfs-utils-1.0.10/utils/gs
        goto out;
 +#endif
  }
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gss_util.c nfs-utils-1.0.10/utils/gssd/gss_util.c
---- nfs-utils-1.0.10.orig/utils/gssd/gss_util.c        2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/gss_util.c     2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gss_util.c nfs-utils-1.0.10.lustre/utils/gssd/gss_util.c
+--- nfs-utils-1.0.10/utils/gssd/gss_util.c     2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gss_util.c      2007-05-15 13:01:35.000000000 -0600
 @@ -87,9 +87,16 @@
  #ifdef HAVE_COM_ERR_H
  #include <com_err.h>
@@ -1839,9 +1839,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gss_util.c nfs-utils-1.0.10/utils/gss
 +      return retval;
 +}
 +
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/gss_util.h nfs-utils-1.0.10/utils/gssd/gss_util.h
---- nfs-utils-1.0.10.orig/utils/gssd/gss_util.h        2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/gss_util.h     2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/gss_util.h nfs-utils-1.0.10.lustre/utils/gssd/gss_util.h
+--- nfs-utils-1.0.10/utils/gssd/gss_util.h     2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/gss_util.h      2007-05-15 13:01:35.000000000 -0600
 @@ -32,14 +32,14 @@
  #define _GSS_UTIL_H_
  
@@ -1859,9 +1859,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/gss_util.h nfs-utils-1.0.10/utils/gss
 +int gssd_get_local_realm(void);
  
  #endif /* _GSS_UTIL_H_ */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gssd/krb5_util.c
---- nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c       2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/krb5_util.c    2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/krb5_util.c nfs-utils-1.0.10.lustre/utils/gssd/krb5_util.c
+--- nfs-utils-1.0.10/utils/gssd/krb5_util.c    2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/krb5_util.c     2007-05-15 13:01:35.000000000 -0600
 @@ -99,12 +99,15 @@
  #include <rpc/rpc.h>
  #include <sys/types.h>
@@ -1962,7 +1962,20 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
                printerr(2, "INFO: Credentials in CC '%s' are good until %d\n",
                         ple->ccname, ple->endtime);
                code = 0;
-@@ -325,11 +374,7 @@ gssd_get_single_krb5_cred(krb5_context c
+@@ -314,6 +363,12 @@ gssd_get_single_krb5_cred(krb5_context c
+       /* set a short lifetime (for debugging only!) */
+       printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n");
+       krb5_get_init_creds_opt_set_tkt_life(&options, 5*60);
++#else
++      /* FIXME try to get the ticket with lifetime as long as possible,
++       * to work around ticket-expiry + recovery problem in cmd3-11
++       * remove this!!!
++       */
++      krb5_get_init_creds_opt_set_tkt_life(&options, 30*24*60*60);
+ #endif
+         if ((code = krb5_get_init_creds_keytab(context, &my_creds, ple->princ,
+                                         kt, 0, NULL, &options))) {
+@@ -325,11 +380,7 @@ gssd_get_single_krb5_cred(krb5_context c
                            "principal '%s' from keytab '%s'\n",
                         error_message(code),
                         pname ? pname : "<unparsable>", kt_name);
@@ -1975,7 +1988,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
                goto out;
        }
  
-@@ -378,15 +423,7 @@ gssd_get_single_krb5_cred(krb5_context c
+@@ -378,15 +429,7 @@ gssd_get_single_krb5_cred(krb5_context c
        return (code);
  }
  
@@ -1992,7 +2005,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
  {
        struct gssd_k5_kt_princ *ple;
  #ifdef HAVE_KRB5
-@@ -396,18 +433,76 @@ gssd_have_realm_ple(void *r)
+@@ -396,18 +439,76 @@ gssd_have_realm_ple(void *r)
  #endif
  
        for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) {
@@ -2077,7 +2090,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
  /*
   * Process the given keytab file and create a list of principals we
   * might use to perform mount operations.
-@@ -451,82 +546,106 @@ gssd_process_krb5_keytab(krb5_context co
+@@ -451,82 +552,106 @@ gssd_process_krb5_keytab(krb5_context co
                }
                printerr(2, "Processing keytab entry for principal '%s'\n",
                         pname);
@@ -2253,40 +2266,15 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
        }
  
        if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) {
-@@ -634,14 +753,21 @@ parse_enctypes(char *enctypes)
-  *    void
-  */
- void
--gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
-+gssd_setup_krb5_user_gss_ccache(uint64_t pag, uid_t uid, char *servername)
- {
-       char                    buf[MAX_NETOBJ_SZ];
-       struct dirent           *d;
--      printerr(2, "getting credentials for client with uid %u for "
--                  "server %s\n", uid, servername);
-+      printerr(2, "getting credentials for client with pag %llx/uid %u for "
-+                  "server %s\n", pag, uid, servername);
+@@ -642,6 +767,7 @@ gssd_setup_krb5_user_gss_ccache(uid_t ui
+       printerr(2, "getting credentials for client with uid %u for "
+                   "server %s\n", uid, servername);
        memset(buf, 0, sizeof(buf));
 +
-+      if (pag != uid) {
-+              snprintf(buf, sizeof(buf), "FILE:%s/%spag_%llx",
-+                       ccachedir, GSSD_DEFAULT_CRED_PREFIX, pag);
-+              goto set_ccname;
-+      }
-+
        if (gssd_find_existing_krb5_ccache(uid, &d)) {
                snprintf(buf, sizeof(buf), "FILE:%s/%s",
                        ccachedir, d->d_name);
-@@ -652,6 +778,7 @@ gssd_setup_krb5_user_gss_ccache(uid_t ui
-                       ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
-       printerr(2, "using %s as credentials cache for client with "
-                   "uid %u for server %s\n", buf, uid, servername);
-+set_ccname:
-       gssd_set_krb5_ccache_name(buf);
- }
-@@ -702,7 +829,7 @@ gssd_refresh_krb5_machine_creds(void)
+@@ -702,7 +828,7 @@ gssd_refresh_krb5_machine_creds(void)
                goto out;
        }
  
@@ -2295,7 +2283,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
  
        if ((code = krb5_kt_resolve(context, keytabfile, &kt))) {
                printerr(0, "ERROR: %s while resolving keytab '%s'\n",
-@@ -717,12 +844,12 @@ gssd_refresh_krb5_machine_creds(void)
+@@ -717,12 +843,12 @@ gssd_refresh_krb5_machine_creds(void)
                if (gssd_k5_kt_princ_list == NULL) {
                        printerr(0, "ERROR: No usable keytab entries found in "
                                    "keytab '%s'\n", keytabfile);
@@ -2313,7 +2301,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
                }
        }
  
-@@ -872,6 +999,7 @@ gssd_destroy_krb5_machine_creds(void)
+@@ -872,6 +998,7 @@ gssd_destroy_krb5_machine_creds(void)
        krb5_free_context(context);
  }
  
@@ -2321,7 +2309,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
  #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
  /*
   * this routine obtains a credentials handle via gss_acquire_cred()
-@@ -927,6 +1055,7 @@ limit_krb5_enctypes(struct rpc_gss_sec *
+@@ -927,6 +1054,7 @@ limit_krb5_enctypes(struct rpc_gss_sec *
        return 0;
  }
  #endif        /* HAVE_SET_ALLOWABLE_ENCTYPES */
@@ -2329,10 +2317,10 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.c nfs-utils-1.0.10/utils/gs
  
  /*
   * Obtain supported enctypes from kernel.
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.h nfs-utils-1.0.10/utils/gssd/krb5_util.h
---- nfs-utils-1.0.10.orig/utils/gssd/krb5_util.h       2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/krb5_util.h    2006-12-15 15:12:23.000000000 -0700
-@@ -10,13 +10,15 @@
+diff -rNup nfs-utils-1.0.10/utils/gssd/krb5_util.h nfs-utils-1.0.10.lustre/utils/gssd/krb5_util.h
+--- nfs-utils-1.0.10/utils/gssd/krb5_util.h    2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/krb5_util.h     2007-05-15 13:01:35.000000000 -0600
+@@ -10,6 +10,8 @@
  struct gssd_k5_kt_princ {
        struct gssd_k5_kt_princ *next;
        krb5_principal princ;
@@ -2341,14 +2329,6 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.h nfs-utils-1.0.10/utils/gs
        char *ccname;
        char *realm;
        krb5_timestamp endtime;
- };
--void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername);
-+void gssd_setup_krb5_user_gss_ccache(uint64_t pag, uid_t uid, char *servername);
- int  gssd_get_krb5_machine_cred_list(char ***list);
- int  gssd_refresh_krb5_machine_creds(void);
- void gssd_free_krb5_machine_cred_list(char **list);
 @@ -25,8 +27,4 @@ void gssd_destroy_krb5_machine_creds(voi
  void gssd_obtain_kernel_krb5_info(void);
  
@@ -2358,10 +2338,833 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/krb5_util.h nfs-utils-1.0.10/utils/gs
 -#endif
 -
  #endif /* KRB5_UTIL_H */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gssd/lsupport.c
---- nfs-utils-1.0.10.orig/utils/gssd/lsupport.c        2006-11-15 21:41:25.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/lsupport.c     2006-12-15 15:12:23.000000000 -0700
-@@ -0,0 +1,782 @@
+diff -rNup nfs-utils-1.0.10/utils/gssd/lgss_keyring.c nfs-utils-1.0.10.lustre/utils/gssd/lgss_keyring.c
+--- nfs-utils-1.0.10/utils/gssd/lgss_keyring.c 1969-12-31 17:00:00.000000000 -0700
++++ nfs-utils-1.0.10.lustre/utils/gssd/lgss_keyring.c  2007-05-15 13:01:35.000000000 -0600
+@@ -0,0 +1,778 @@
++/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
++ * vim:expandtab:shiftwidth=8:tabstop=8:
++ *
++ *  lucall_keyring.c
++ *  user-space upcall to create GSS context, using keyring interface to kernel
++ *
++ *  Copyright (c) 2007 Cluster File Systems, Inc.
++ *   Author: Eric Mei <ericm@clusterfs.com>
++ *
++ *   This file is part of the Lustre file system, http://www.lustre.org
++ *   Lustre is a trademark of Cluster File Systems, Inc.
++ *
++ *   You may have signed or agreed to another license before downloading
++ *   this software.  If so, you are bound by the terms and conditions
++ *   of that agreement, and the following does not apply to you.  See the
++ *   LICENSE file included with this distribution for more information.
++ *
++ *   If you did not agree to a different license, then this copy of Lustre
++ *   is open source software; you can redistribute it and/or modify it
++ *   under the terms of version 2 of the GNU General Public License as
++ *   published by the Free Software Foundation.
++ *
++ *   In either case, Lustre is distributed in the hope that it will be
++ *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
++ *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *   license text for more details.
++ */
++
++#include <unistd.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <fcntl.h>
++#include <string.h>
++#include <errno.h>
++#include <stdarg.h>
++#include <syslog.h>
++#include <assert.h>
++#include <pwd.h>
++#include <keyutils.h>
++#include <gssapi/gssapi.h>
++
++#include <libcfs/libcfs.h>
++
++#include "lsupport.h"
++#include "write_bytes.h"
++#include "krb5_util.h"
++#include "gss_oids.h"
++#include "context.h"
++
++/*
++ * XXX TEMP to satisfy link. should be removed!!!
++ */
++char ccachedir[PATH_MAX] = "/tmp";
++char keytabfile[PATH_MAX] = "/etc/krb5.keytab";
++int  use_memcache = 0;
++
++/****************************************
++ * log facilities                       *
++ ****************************************/
++
++/*
++ * log level:
++ * 0: critical error messages
++ * 1: warning included
++ * 2: debugging
++ * 3: excessive messages
++ */
++typedef enum {
++        LL_ERR          = 0,
++        LL_WARN         = 1,
++        LL_INFO         = 2,
++        LL_TRACE        = 3,
++} loglevel_t;
++
++loglevel_t g_log_level = LL_TRACE;
++
++static void logmsg(loglevel_t level, const char *format, ...)
++{
++        char    buf[1024];
++        int     offset;
++        va_list ap;
++
++        if (level > g_log_level)
++                return;
++
++        offset = snprintf(buf, sizeof(buf), "[%d]: ", getpid());
++
++        va_start(ap, format);
++        vsnprintf(buf + offset, sizeof(buf) - offset, format, ap);
++        va_end(ap);
++
++        syslog(LOG_INFO, "%s", buf);
++}
++
++static void logmsg_gss(loglevel_t level, const gss_OID mech,
++                       u_int32_t major, u_int32_t minor,
++                       const char *format, ...)
++{
++        va_list         ap;
++        u_int32_t       maj_stat1, min_stat1;
++        u_int32_t       maj_stat2, min_stat2;
++        gss_buffer_desc maj_gss_buf = GSS_C_EMPTY_BUFFER;
++        gss_buffer_desc min_gss_buf = GSS_C_EMPTY_BUFFER;
++        char            maj_buf[30], min_buf[30];
++        char           *maj, *min;
++        uint32_t        msg_ctx = 0;
++
++        if (level > g_log_level)
++                return;
++
++        /* Get major status message */
++        maj_stat1 = gss_display_status(&min_stat1, major,
++                GSS_C_GSS_CODE, mech, &msg_ctx, &maj_gss_buf);
++
++        if (maj_stat1 != GSS_S_COMPLETE) {
++                snprintf(maj_buf, sizeof(maj_buf), "(0x%08x)", major);
++                maj = &maj_buf[0];
++        } else {
++                maj = maj_gss_buf.value;
++        }
++
++        /* Get minor status message */
++        maj_stat2 = gss_display_status(&min_stat2, minor,
++                GSS_C_MECH_CODE, mech, &msg_ctx, &min_gss_buf);
++
++        if (maj_stat2 != GSS_S_COMPLETE) {
++                snprintf(min_buf, sizeof(min_buf), "(0x%08x)", minor);
++                min = &min_buf[0];
++        } else {
++                min = min_gss_buf.value;
++        }
++
++        syslog(LOG_INFO, "GSS-API: %s - %s\n", maj, min);
++
++        va_start(ap, format);
++        vsyslog(LOG_INFO, format, ap);
++        va_end(ap);
++
++        if (maj_gss_buf.length != 0)
++                (void) gss_release_buffer(&min_stat1, &maj_gss_buf);
++        if (min_gss_buf.length != 0)
++                (void) gss_release_buffer(&min_stat2, &min_gss_buf);
++}
++
++#define lassert(exp)                                                    \
++        {                                                               \
++                if ((int)(exp) == 0) {                                  \
++                        logmsg(LL_ERR, "ASSERTION FAILED: #exp");       \
++                        exit(-1);                                       \
++                }                                                       \
++        }
++
++/****************************************
++ * global declaration                   *
++ ****************************************/
++
++typedef enum {
++        LGSS_SVC_MDS    = 0,
++        LGSS_SVC_OSS    = 1,
++        LGSS_SVC_MAX
++} lgss_svc_t;
++
++const char *lgss_svc_name[LGSS_SVC_MAX] = {
++        [LGSS_SVC_MDS] = "lustre_mds",
++        [LGSS_SVC_OSS] = "lustre_oss",
++};
++
++typedef enum {
++        LGSS_AUTH_KRB5,
++} lgss_auth_t;
++
++/*
++ * all data about negotiation
++ */
++struct lgss_nego_data {
++        uint32_t        lnd_established:1;
++        uint32_t        lnd_uid;
++        uint32_t        lnd_lsvc;
++        char           *lnd_uuid;
++
++        gss_OID         lnd_mech;               /* mech OID */
++        gss_name_t      lnd_svc_name;           /* service name */
++        u_int           lnd_req_flags;          /* request flags */
++        gss_cred_id_t   lnd_cred;               /* credential */
++        gss_ctx_id_t    lnd_ctx;                /* session context */
++        gss_buffer_desc lnd_rmt_ctx;            /* remote handle of context */
++        uint32_t        lnd_seq_win;            /* sequence window */
++
++        int             lnd_rpc_err;
++        int             lnd_gss_err;
++};
++
++/*
++ * context creation response
++ */
++struct lgss_init_res {
++        gss_buffer_desc gr_ctx;         /* context handle */
++        u_int           gr_major;       /* major status */
++        u_int           gr_minor;       /* minor status */
++        u_int           gr_win;         /* sequence window */
++        gss_buffer_desc gr_token;       /* token */
++};
++
++struct keyring_upcall_param {
++        uint32_t        kup_ver;
++        uint32_t        kup_uid;
++        uint32_t        kup_gid;
++        uint32_t        kup_svc;
++        uint64_t        kup_nid;
++        char            kup_tgt[64];
++};
++
++/*
++ * gss target string of lustre service we are negotiating for
++ */
++char *g_service = NULL;
++
++/****************************************
++ * child process: gss negotiation       *
++ ****************************************/
++
++#define INIT_CHANNEL    "/proc/fs/lustre/sptlrpc/gss/init_channel"
++
++int do_nego_rpc(struct lgss_nego_data *lnd,
++                gss_buffer_desc *gss_token,
++                struct lgss_init_res *gr)
++{
++        struct lgssd_ioctl_param  param;
++        struct passwd            *pw;
++        int                       fd, ret, res;
++        char                      outbuf[8192];
++        unsigned int             *p;
++
++        logmsg(LL_TRACE, "do_nego_rpc: get started\n");
++
++        pw = getpwuid(lnd->lnd_uid);
++        if (!pw) {
++                logmsg(LL_ERR, "no uid %u in local user database\n",
++                       lnd->lnd_uid);
++                return -1;
++        }
++
++        param.version = GSSD_INTERFACE_VERSION;
++        param.uuid = lnd->lnd_uuid;
++        param.lustre_svc = lnd->lnd_lsvc;
++        param.uid = lnd->lnd_uid;
++        param.gid = pw->pw_gid;
++        param.send_token_size = gss_token->length;
++        param.send_token = (char *) gss_token->value;
++        param.reply_buf_size = sizeof(outbuf);
++        param.reply_buf = outbuf;
++
++        logmsg(LL_TRACE, "to open " INIT_CHANNEL "\n");
++
++        fd = open(INIT_CHANNEL, O_WRONLY);
++        if (fd < 0) {
++                logmsg(LL_ERR, "can't open " INIT_CHANNEL "\n");
++                return -1;
++        }
++
++        logmsg(LL_TRACE, "to down-write\n");
++
++        ret = write(fd, &param, sizeof(param));
++        if (ret != sizeof(param)) {
++                logmsg(LL_ERR, "lustre ioctl err: %d\n", strerror(errno));
++                close(fd);
++                return -1;
++        }
++        close(fd);
++
++        logmsg(LL_TRACE, "do_nego_rpc: to parse reply\n");
++        if (param.status) {
++                logmsg(LL_ERR, "status: %d (%s)\n",
++                       param.status, strerror((int)param.status));
++
++                if (param.status == -ETIMEDOUT) {
++                        /* kernel return -ETIMEDOUT means the rpc timedout,
++                         * we should notify the caller to reinitiate the
++                         * gss negotiation, by return -ERESTART
++                         */
++                        lnd->lnd_rpc_err = -ERESTART;
++                        lnd->lnd_gss_err = 0;
++                } else {
++                        lnd->lnd_rpc_err = param.status;
++                        lnd->lnd_gss_err = 0;
++                }
++
++                return -1;
++        }
++
++        p = (unsigned int *)outbuf;
++        res = *p++;
++        gr->gr_major = *p++;
++        gr->gr_minor = *p++;
++        gr->gr_win = *p++;
++
++        gr->gr_ctx.length = *p++;
++        gr->gr_ctx.value = malloc(gr->gr_ctx.length);
++        memcpy(gr->gr_ctx.value, p, gr->gr_ctx.length);
++        p += (((gr->gr_ctx.length + 3) & ~3) / 4);
++
++        gr->gr_token.length = *p++;
++        gr->gr_token.value = malloc(gr->gr_token.length);
++        memcpy(gr->gr_token.value, p, gr->gr_token.length);
++        p += (((gr->gr_token.length + 3) & ~3) / 4);
++
++        logmsg(LL_INFO, "do_nego_rpc: receive handle len %d, token len %d\n",
++               gr->gr_ctx.length, gr->gr_token.length);
++        return 0;
++}
++
++/*
++ * if return error, the lnd_rpc_err or lnd_gss_err is set.
++ */
++int lgssc_negotiation(struct lgss_nego_data *lnd)
++{
++        struct lgss_init_res    gr;
++        gss_buffer_desc        *recv_tokenp, send_token;
++        OM_uint32               maj_stat, min_stat, ret_flags;
++        int                     call_stat;
++
++        logmsg(LL_TRACE, "start negotiation\n");
++
++        /* GSS context establishment loop. */
++        memset(&gr, 0, sizeof(gr));
++        recv_tokenp = GSS_C_NO_BUFFER;
++
++        for (;;) {
++#if 0
++                /* print the token we just received */
++                if (recv_tokenp != GSS_C_NO_BUFFER) {
++                        printerr(3, "The received token length %d\n",
++                                 recv_tokenp->length);
++                        print_hexl(3, recv_tokenp->value, recv_tokenp->length);
++                }
++#endif
++
++                maj_stat = gss_init_sec_context(&min_stat,
++                                                lnd->lnd_cred,
++                                                &lnd->lnd_ctx,
++                                                lnd->lnd_svc_name,
++                                                lnd->lnd_mech,
++                                                lnd->lnd_req_flags,
++                                                0,            /* time req */
++                                                NULL,         /* channel */
++                                                recv_tokenp,
++                                                NULL,         /* used mech */
++                                                &send_token,
++                                                &ret_flags,
++                                                NULL);        /* time rec */
++
++                if (recv_tokenp != GSS_C_NO_BUFFER) {
++                        gss_release_buffer(&min_stat, &gr.gr_token);
++                        recv_tokenp = GSS_C_NO_BUFFER;
++                }
++
++                if (maj_stat != GSS_S_COMPLETE &&
++                    maj_stat != GSS_S_CONTINUE_NEEDED) {
++                        lnd->lnd_gss_err = maj_stat;
++
++                        logmsg_gss(LL_ERR, lnd->lnd_mech, maj_stat, min_stat,
++                                   "failed init context\n");
++                        break;
++                }
++
++                if (send_token.length != 0) {
++                        memset(&gr, 0, sizeof(gr));
++#if 0
++                        /* print the token we are about to send */
++                        printerr(3, "token being sent length %d\n",
++                                 send_token.length);
++                        print_hexl(3, send_token.value, send_token.length);
++#endif
++                        call_stat = do_nego_rpc(lnd, &send_token, &gr);
++                        gss_release_buffer(&min_stat, &send_token);
++
++                        if (call_stat != 0 ||
++                            (gr.gr_major != GSS_S_COMPLETE &&
++                             gr.gr_major != GSS_S_CONTINUE_NEEDED)) {
++                                lnd->lnd_rpc_err = call_stat;
++                                lnd->lnd_gss_err = gr.gr_major;
++
++                                logmsg(LL_ERR, "call stat %d, major stat %x\n",
++                                       call_stat, gr.gr_major);
++                                return -1;
++                        }
++
++                        if (gr.gr_ctx.length != 0) {
++                                if (lnd->lnd_rmt_ctx.value)
++                                        gss_release_buffer(&min_stat,
++                                                           &lnd->lnd_rmt_ctx);
++                                lnd->lnd_rmt_ctx = gr.gr_ctx;
++                        }
++
++                        if (gr.gr_token.length != 0) {
++                                if (maj_stat != GSS_S_CONTINUE_NEEDED)
++                                        break;
++                                recv_tokenp = &gr.gr_token;
++                        }
++                }
++
++                /* GSS_S_COMPLETE => check gss header verifier,
++                 * usually checked in gss_validate
++                 */
++                if (maj_stat == GSS_S_COMPLETE) {
++                        lnd->lnd_established = 1;
++                        lnd->lnd_seq_win = gr.gr_win;
++                        break;
++                }
++        }
++
++        /* End context negotiation loop. */
++        if (!lnd->lnd_established) {
++                if (gr.gr_token.length != 0)
++                        gss_release_buffer(&min_stat, &gr.gr_token);
++
++                if (lnd->lnd_gss_err == GSS_S_COMPLETE)
++                        lnd->lnd_rpc_err = -EACCES;
++
++                logmsg(LL_ERR, "context negotiation failed\n");
++                return -1;
++        }
++
++        logmsg(LL_INFO, "successfully negotiated context\n");
++        return 0;
++}
++
++int construct_service(struct keyring_upcall_param *kup)
++{
++        const int       max_namelen = 512;
++        char            namebuf[max_namelen];
++        int             alloc_size;
++
++        lassert(g_service == NULL);
++
++        if (kup->kup_svc >= LGSS_SVC_MAX) {
++                logmsg(LL_ERR, "invalid lgss service %d\n", kup->kup_svc);
++                return 1;
++        }
++
++        if (lnet_nid2hostname(kup->kup_nid, namebuf, max_namelen))
++                return 1;
++
++        alloc_size = 32 + strlen(namebuf);
++
++        g_service = malloc(alloc_size);
++        if (g_service == NULL) {
++                logmsg(LL_ERR, "can't malloc %d bytes\n", alloc_size);
++                return 1;
++        }
++
++        snprintf(g_service, alloc_size, "%s@%s",
++                 lgss_svc_name[kup->kup_svc], namebuf);
++
++        logmsg(LL_INFO, "constructed service: %s\n", g_service);
++        return 0;
++}
++
++/*
++ * if return error, the lnd_rpc_err or lnd_gss_err is set.
++ */
++int lgssc_init_nego_data(struct lgss_nego_data *lnd,
++                         struct keyring_upcall_param *kup,
++                         lgss_auth_t authtype)
++{
++        gss_buffer_desc         sname;
++        OM_uint32               maj_stat, min_stat;
++
++        memset(lnd, 0, sizeof(*lnd));
++
++        lnd->lnd_uid = kup->kup_uid;
++        lnd->lnd_lsvc = kup->kup_svc;
++        lnd->lnd_uuid = kup->kup_tgt;
++
++        lnd->lnd_established = 0;
++        lnd->lnd_svc_name = GSS_C_NO_NAME;
++        lnd->lnd_cred = GSS_C_NO_CREDENTIAL;
++        lnd->lnd_ctx = GSS_C_NO_CONTEXT;
++        lnd->lnd_rmt_ctx = (gss_buffer_desc) GSS_C_EMPTY_BUFFER;
++        lnd->lnd_seq_win = 0;
++
++        switch (authtype) {
++        case LGSS_AUTH_KRB5:
++                lnd->lnd_mech = (gss_OID) &krb5oid;
++                lnd->lnd_req_flags = GSS_C_MUTUAL_FLAG;
++                break;
++        default:
++                logmsg(LL_ERR, "invalid auth type: %d\n", authtype);
++                lnd->lnd_rpc_err = -EACCES;
++                return -1;
++        }
++
++        sname.value = g_service;
++        sname.length = strlen(g_service);
++
++        maj_stat = gss_import_name(&min_stat, &sname,
++                                   (gss_OID) GSS_C_NT_HOSTBASED_SERVICE,
++                                   &lnd->lnd_svc_name);
++        if (maj_stat != GSS_S_COMPLETE) {
++                logmsg_gss(LL_ERR, lnd->lnd_mech, maj_stat, min_stat,
++                           "can't import svc name\n");
++                lnd->lnd_gss_err = maj_stat;
++                return -1;
++        }
++
++        return 0;
++}
++
++void lgssc_fini_nego_data(struct lgss_nego_data *lnd)
++{
++        OM_uint32       maj_stat, min_stat;
++
++        if (lnd->lnd_svc_name != GSS_C_NO_NAME) {
++                maj_stat = gss_release_name(&min_stat, &lnd->lnd_svc_name);
++                if (maj_stat != GSS_S_COMPLETE)
++                        logmsg_gss(LL_ERR, lnd->lnd_mech, maj_stat, min_stat,
++                                   "can't release service name\n");
++        }
++
++        if (lnd->lnd_cred != GSS_C_NO_CREDENTIAL) {
++                maj_stat = gss_release_cred(&min_stat, &lnd->lnd_cred);
++                if (maj_stat != GSS_S_COMPLETE)
++                        logmsg_gss(LL_ERR, lnd->lnd_mech, maj_stat, min_stat,
++                                   "can't release credential\n");
++        }
++}
++
++static
++int error_kernel_key(key_serial_t keyid, int rpc_error, int gss_error)
++{
++        int      seqwin = 0;
++        char     buf[32];
++        char    *p, *end;
++
++        logmsg(LL_TRACE, "revoking kernel key 0x%x\n", keyid);
++
++        p = buf;
++        end = buf + sizeof(buf);
++
++        WRITE_BYTES(&p, end, seqwin);
++        WRITE_BYTES(&p, end, rpc_error);
++        WRITE_BYTES(&p, end, gss_error);
++
++again:
++        if (keyctl_update(keyid, buf, p - buf)) {
++                if (errno != EAGAIN) {
++                        logmsg(LL_ERR, "failed to revoke key 0x%x: %s\n",
++                               keyid, strerror(errno));
++                        return -1;
++                }
++
++                logmsg(LL_WARN, "revoke key 0x%x too soon, try again\n", keyid);
++                sleep(2);
++                goto again;
++        }
++
++        logmsg(LL_INFO, "successfully revoke key 0x%x\n", keyid);
++        return 0;
++}
++
++static
++int update_kernel_key(key_serial_t keyid,
++                      struct lgss_nego_data *lnd,
++                      gss_buffer_desc *ctx_token)
++{
++        char        *buf = NULL, *p = NULL, *end = NULL;
++        unsigned int buf_size = 0;
++        int          rc;
++
++        logmsg(LL_TRACE, "updating kernel key 0x%x\n", keyid);
++
++        buf_size = sizeof(lnd->lnd_seq_win) +
++                   sizeof(lnd->lnd_rmt_ctx.length) + lnd->lnd_rmt_ctx.length +
++                   sizeof(ctx_token->length) + ctx_token->length;
++        buf = malloc(buf_size);
++        if (buf == NULL) {
++                logmsg(LL_ERR, "failed to alloc key update buf: size %d\n",
++                       buf_size);
++                return 1;
++        }
++
++        p = buf;
++        end = buf + buf_size;
++        rc = -1;
++
++        if (WRITE_BYTES(&p, end, lnd->lnd_seq_win))
++                goto out;
++        if (write_buffer(&p, end, &lnd->lnd_rmt_ctx))
++                goto out;
++        if (write_buffer(&p, end, ctx_token))
++                goto out;
++
++again:
++        if (keyctl_update(keyid, buf, p - buf)) {
++                if (errno != EAGAIN) {
++                        logmsg(LL_ERR, "failed to update key 0x%x: %s\n",
++                               keyid, strerror(errno));
++                        goto out;
++                }
++
++                logmsg(LL_WARN, "update key 0x%x too soon, try again\n", keyid);
++                sleep(2);
++                goto again;
++        }
++
++        rc = 0;
++        logmsg(LL_INFO, "successfully updated key 0x%x\n", keyid);
++out:
++        free(buf);
++        return rc;
++}
++
++/*
++ * note we can't assume authority in child process
++ */
++int lgssc_kr_negotiate(key_serial_t keyid, struct keyring_upcall_param *kup)
++{
++        struct lgss_nego_data   lnd;
++        gss_buffer_desc         token = GSS_C_EMPTY_BUFFER;
++        OM_uint32               min_stat;
++        int                     rc;
++
++        logmsg(LL_TRACE, "child start on behalf of key 0x%x\n", keyid);
++
++        if (kup->kup_gid != 0 && setregid(kup->kup_gid, kup->kup_gid)) {
++                logmsg(LL_ERR, "key 0x%x, failed set gids to %u: %s\n",
++                       keyid, kup->kup_gid, strerror(errno));
++        }
++
++        if (kup->kup_uid != 0 && setreuid(kup->kup_uid, kup->kup_uid)) {
++                logmsg(LL_ERR, "key 0x%x, failed set uids to %u: %s\n",
++                       keyid, kup->kup_uid, strerror(errno));
++        }
++
++        /*
++         * link to session keyring, allow the key to be found.
++         */
++        if (keyctl_link(keyid, KEY_SPEC_SESSION_KEYRING)) {
++                logmsg(LL_ERR, "key 0x%x, failed to link to session "
++                       "keyring: %s\n", keyid, strerror(errno));
++                error_kernel_key(keyid, -EACCES, 0);
++                return -1;
++        }
++
++        rc = -1;
++        if (construct_service(kup)) {
++                error_kernel_key(keyid, -EACCES, 0);
++                goto out_unlink;
++        }
++
++        if (1/* kup->kup_uid == 0 FIXME */) {
++                gssd_setup_krb5_user_gss_ccache(kup->kup_uid, g_service);
++        }
++
++        if (lgssc_init_nego_data(&lnd, kup, LGSS_AUTH_KRB5)) {
++                error_kernel_key(keyid, lnd.lnd_rpc_err, lnd.lnd_gss_err);
++                goto out_unlink;
++        }
++
++        rc = lgssc_negotiation(&lnd);
++        if (rc) {
++                error_kernel_key(keyid, lnd.lnd_rpc_err, lnd.lnd_gss_err);
++                goto out;
++        }
++
++        rc = serialize_context_for_kernel(lnd.lnd_ctx, &token, lnd.lnd_mech);
++        if (rc) {
++                error_kernel_key(keyid, rc, lnd.lnd_gss_err);
++
++                logmsg(LL_ERR, "failed to export context\n");
++                goto out;
++        }
++
++        rc = update_kernel_key(keyid,  &lnd, &token);
++        if (rc)
++                goto out;
++
++        rc = 0;
++        logmsg(LL_INFO, "key update OK!\n");
++out:
++        if (token.length != 0)
++                gss_release_buffer(&min_stat, &token);
++
++        lgssc_fini_nego_data(&lnd);
++
++out_unlink:
++        if (keyctl_unlink(keyid, KEY_SPEC_SESSION_KEYRING)) {
++                logmsg(LL_ERR, "failed to unlink key %d: %s\n",
++                       keyid, strerror(errno));
++        }
++
++        return rc;
++}
++
++/****************************************
++ * main process                         *
++ ****************************************/
++
++int main(int argc, char *argv[])
++{
++        struct keyring_upcall_param     uparam;
++        key_serial_t                    keyid;
++        key_serial_t                    /*tring, pring, */sring;
++        key_serial_t                    inst_keyring;
++        int                             is_root;
++        pid_t                           child;
++
++        if (argc != 10 + 1) {
++                logmsg(LL_ERR, "Invalid parameter number %d\n", argc);
++                return 1;
++        }
++
++#if 0
++        logmsg(LL_TRACE, "OP:       %s\n", argv[1]);
++        logmsg(LL_TRACE, "KeyID:    %s\n", argv[2]);
++        logmsg(LL_TRACE, "KeyType:  %s\n", argv[3]);
++        logmsg(LL_TRACE, "KeyDesc:  %s\n", argv[4]);
++        logmsg(LL_TRACE, "COInfo:   %s\n", argv[5]);
++        logmsg(LL_TRACE, "UID:      %s\n", argv[6]);
++        logmsg(LL_TRACE, "GID:      %s\n", argv[7]);
++        logmsg(LL_TRACE, "TKeyring: %s\n", argv[8]);
++        logmsg(LL_TRACE, "PKeyring: %s\n", argv[9]);
++        logmsg(LL_TRACE, "SKeyring: %s\n", argv[10]);
++#endif
++        logmsg(LL_INFO, "[%u/%u]: key %s, desc %s, uid %s, sring %s\n",
++               getuid(), geteuid(),
++               argv[2], argv[4], argv[6], argv[10]);
++
++        memset(&uparam, 0, sizeof(uparam));
++
++        if (strcmp(argv[1], "create") != 0) {
++                logmsg(LL_ERR, "invalid OP %s\n", argv[1]);
++                return 1;
++        }
++
++        if (sscanf(argv[2], "%d", &keyid) != 1) {
++                logmsg(LL_ERR, "can't extract KeyID\n");
++                return 1;
++        }
++
++        if (sscanf(argv[6], "%d", &uparam.kup_uid) != 1) {
++                logmsg(LL_ERR, "can't extract uid\n");
++                return 1;
++        }
++
++        if (sscanf(argv[10], "%d", &sring) != 1) {
++                logmsg(LL_ERR, "can't extract session keyring\n");
++                return 1;
++        }
++
++        if (sscanf(argv[5], "%d:%d:%Lx:%s", &is_root, &uparam.kup_svc,
++                   &uparam.kup_nid, uparam.kup_tgt) != 4) {
++                logmsg(LL_ERR, "can't extract callout info: %s\n", argv[5]);
++                return 1;
++        }
++        logmsg(LL_INFO, "coinfo: fl %d, svc %d, nid 0x%Lx, tgt %s\n",
++               is_root, uparam.kup_svc, uparam.kup_nid, uparam.kup_tgt);
++
++        if (is_root)
++                inst_keyring = 0;
++        else
++                inst_keyring = KEY_SPEC_SESSION_KEYRING;
++
++        if (keyctl_instantiate(keyid, NULL, 0, inst_keyring)) {
++                logmsg(LL_ERR, "key instantiate: %s\n", strerror(errno));
++                return 1;
++        }
++
++        child = fork();
++        if (child == -1) {
++                logmsg(LL_ERR, "can't create child: %s\n", strerror(errno));
++                return 1;
++        } else if (child == 0) {
++                return lgssc_kr_negotiate(keyid, &uparam);
++        }
++
++        return 0;
++}
+diff -rNup nfs-utils-1.0.10/utils/gssd/l_idmap.c nfs-utils-1.0.10.lustre/utils/gssd/l_idmap.c
+--- nfs-utils-1.0.10/utils/gssd/l_idmap.c      1969-12-31 17:00:00.000000000 -0700
++++ nfs-utils-1.0.10.lustre/utils/gssd/l_idmap.c       2007-05-15 13:01:35.000000000 -0600
+@@ -0,0 +1,37 @@
++#include <sys/types.h>
++#include <stdlib.h>
++#include <stdio.h>
++
++#include "lsupport.h"
++
++int main(int argc, char **argv)
++{
++      lnet_nid_t nid;
++      uid_t uid;
++      int rc;
++
++      if (argc < 3) {
++              printf("Usage:\n"
++                     "%s <princ> <nid>\n",
++                     basename(argv[0]));
++              return 1;
++      }
++
++      nid = libcfs_str2nid(argv[2]);
++      if (nid == LNET_NID_ANY) {
++              printf("parse nid %s failed\n", argv[2]);
++              return 1;
++      }
++      rc = lookup_mapping(argv[1], nid, &uid);
++      if (rc == -1) {
++              printf("lookup mapping failed\n");
++              return 1;
++      }
++
++      printf("principal: %s\n"
++             "nid:       %#llx\n"
++             "uid:       %u\n",
++             argv[1], nid, uid);
++
++      return 0;
++}
+diff -rNup nfs-utils-1.0.10/utils/gssd/lsupport.c nfs-utils-1.0.10.lustre/utils/gssd/lsupport.c
+--- nfs-utils-1.0.10/utils/gssd/lsupport.c     1969-12-31 17:00:00.000000000 -0700
++++ nfs-utils-1.0.10.lustre/utils/gssd/lsupport.c      2007-05-15 13:01:35.000000000 -0600
+@@ -0,0 +1,783 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
 + *
@@ -2633,10 +3436,10 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 +} converter[LND_ENUM_END_MARKER] = {
 +        {"UNUSED0",     NULL},
 +        [QSWLND]        = { "QSWLND",   external_nid2hostname},
-+        [SOCKLND]       = { "SOCKLND",  socklnd_nid2hostname},
++        [SOCKLND]       = { "SOCKLND",  socklnd_nid2hostname },
 +        [GMLND]         = { "GMLND",    external_nid2hostname},
 +        [PTLLND]        = { "PTLLND",   external_nid2hostname },
-+        [O2IBLND]       = { "O2IBLND",  external_nid2hostname },
++        [O2IBLND]       = { "O2IBLND",  socklnd_nid2hostname }, /* XXX */
 +        [CIBLND]        = { "CIBLND",   external_nid2hostname },
 +        [OPENIBLND]     = { "OPENIBLND",external_nid2hostname },
 +        [IIBLND]        = { "IIBLND",   external_nid2hostname },
@@ -2937,58 +3740,57 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 + ****************************************/
 +
 +#define MAPPING_GROW_SIZE       512
-+#define MAX_LINE_LEN            1024
++#define MAX_LINE_LEN            256
 +
 +struct user_map_item {
-+        char        *principal; /* NULL means match all */
++        char        *principal; /* NULL means match all, will cause multi->single mapped, FORBID */
 +        lnet_nid_t   nid;
 +        uid_t        uid;
 +};
 +
 +struct user_mapping {
-+        int                   size;
 +        int                   nitems;
 +        struct user_map_item *items;
 +};
 +
-+static struct user_mapping mapping = {0, 0, NULL};
++static struct user_mapping mapping = {0, NULL};
 +/* FIXME to be finished: monitor change of mapping database */
 +static int mapping_mtime = 0;
 +
-+static
 +void cleanup_mapping(void)
 +{
-+        int n;
-+
-+        for (n = 0; n < mapping.nitems; n++) {
-+                if (mapping.items[n].principal)
-+                        free(mapping.items[n].principal);
++        if (mapping.items) {
++                for (; mapping.nitems > 0; mapping.nitems--)
++                        free(mapping.items[mapping.nitems - 1].principal);
++                free(mapping.items);
++                mapping.items = NULL;
 +        }
-+        mapping.nitems = 0;
 +}
 +
-+static
-+int grow_mapping(int size)
++static int grow_mapping(int nitems)
 +{
 +        struct user_map_item *new;
-+        int newsize;
++        int oldsize, newsize;
 +
-+        if (size <= mapping.size)
++        oldsize = (mapping.nitems * sizeof(struct user_map_item) +
++                   MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
++        newsize = (nitems * sizeof(struct user_map_item) +
++                   MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
++        while (newsize <= oldsize)
 +                return 0;
 +
-+        newsize = mapping.size + MAPPING_GROW_SIZE;
-+        while (newsize < size)
-+                newsize += MAPPING_GROW_SIZE;
-+
-+        new = malloc(newsize * sizeof(struct user_map_item));
++        newsize *= MAPPING_GROW_SIZE;
++        new = malloc(newsize);
 +        if (!new) {
 +                printerr(0, "can't alloc mapping size %d\n", newsize);
 +                return -1;
 +        }
-+        memcpy(new, mapping.items, mapping.nitems * sizeof(void*));
-+        free(mapping.items);
++
++        if (mapping.items) {
++                memcpy(new, mapping.items, mapping.nitems * sizeof(struct user_map_item));
++                free(mapping.items);
++        }
 +        mapping.items = new;
-+        mapping.size = newsize;
 +        return 0;
 +}
 +
@@ -3009,16 +3811,16 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 +        return -1;
 +}
 +
-+static
-+int read_mapping_db(void)
++static int read_mapping_db(void)
 +{
 +        char princ[MAX_LINE_LEN];
 +        char nid_str[MAX_LINE_LEN];
 +        char dest[MAX_LINE_LEN];
++        char linebuf[MAX_LINE_LEN];
++        char *line;
 +        lnet_nid_t nid;
 +        uid_t dest_uid;
 +        FILE *f;
-+        char *line, linebuf[MAX_LINE_LEN];
 +
 +        /* cleanup old mappings */
 +        cleanup_mapping();
@@ -3030,52 +3832,53 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 +                return -1;
 +        }
 +
-+        while ((line = fgets(linebuf, MAX_LINE_LEN, f))) {
++        while ((line = fgets(linebuf, MAX_LINE_LEN, f)) != NULL) {
 +                char *name;
 +
 +                if (strlen(line) >= MAX_LINE_LEN) {
 +                        printerr(0, "invalid mapping db: line too long (%d)\n",
 +                                 strlen(line));
-+                        cleanup_mapping();
-+                        fclose(f);
-+                        return -1;
++                        continue;
 +                }
++
 +                if (sscanf(line, "%s %s %s", princ, nid_str, dest) != 3) {
 +                        printerr(0, "mapping db: syntax error\n");
-+                        cleanup_mapping();
-+                        fclose(f);
-+                        return -1;
-+                }
-+                if (grow_mapping(mapping.nitems + 1)) {
-+                        printerr(0, "fail to grow mapping to %d\n",
-+                                 mapping.nitems + 1);
-+                        fclose(f);
-+                        return -1;
++                        continue;
 +                }
++
 +                if (!strcmp(princ, "*")) {
-+                        name = NULL;
++                        printerr(0, "NOT permit \"*\" princ, it will cause multi->single mapped\n");
++                        continue;
 +                } else {
 +                        name = strdup(princ);
 +                        if (!name) {
 +                                printerr(0, "fail to dup str %s\n", princ);
-+                                fclose(f);
-+                                return -1;
++                                continue;
 +                        }
 +                }
++
 +                if (!strcmp(nid_str, "*")) {
 +                        nid = LNET_NID_ANY;
 +                } else {
 +                        nid = libcfs_str2nid(nid_str);
 +                        if (nid == LNET_NID_ANY) {
 +                                printerr(0, "fail to parse nid %s\n", nid_str);
-+                                fclose(f);
-+                                return -1;
++                                free(name);
++                                continue;
 +                        }
 +                }
++
 +                dest_uid = parse_uid(dest);
 +                if (dest_uid == -1) {
 +                        printerr(0, "no valid user: %s\n", dest);
 +                        free(name);
++                        continue;
++                }
++
++                if (grow_mapping(mapping.nitems + 1)) {
++                        printerr(0, "fail to grow mapping to %d\n",
++                                 mapping.nitems + 1);
++                        free(name);
 +                        fclose(f);
 +                        return -1;
 +                }
@@ -3085,9 +3888,10 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 +                mapping.items[mapping.nitems].uid = dest_uid;
 +                mapping.nitems++;
 +                printerr(1, "add mapping: %s(%s/0x%llx) ==> %d\n",
-+                         name ? name : "*", nid_str, nid, dest_uid);
++                         name, nid_str, nid, dest_uid);
 +        }
 +
++        fclose(f);
 +        return 0;
 +}
 +
@@ -3120,6 +3924,8 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 +{
 +        int n;
 +
++        *uid = -1;
++
 +        /* FIXME race condition here */
 +        if (mapping_changed()) {
 +                if (read_mapping_db())
@@ -3131,22 +3937,20 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.c nfs-utils-1.0.10/utils/gss
 +
 +                if (entry->nid != LNET_NID_ANY && entry->nid != nid)
 +                        continue;
-+                if (!entry->principal ||
-+                    !strcasecmp(entry->principal, princ)) {
++                if (!strcasecmp(entry->principal, princ)) {
 +                        printerr(1, "found mapping: %s ==> %d\n",
 +                                 princ, entry->uid);
 +                        *uid = entry->uid;
 +                        return 0;
 +                }
 +        }
++
 +        printerr(2, "no mapping for %s/%#Lx\n", princ, nid);
-+        *uid = -1;
 +        return -1;
 +}
-+
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.h nfs-utils-1.0.10/utils/gssd/lsupport.h
---- nfs-utils-1.0.10.orig/utils/gssd/lsupport.h        2006-11-15 21:41:23.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/lsupport.h     2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/lsupport.h nfs-utils-1.0.10.lustre/utils/gssd/lsupport.h
+--- nfs-utils-1.0.10/utils/gssd/lsupport.h     1969-12-31 17:00:00.000000000 -0700
++++ nfs-utils-1.0.10.lustre/utils/gssd/lsupport.h      2007-05-15 13:01:35.000000000 -0600
 @@ -0,0 +1,89 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -3177,7 +3981,6 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.h nfs-utils-1.0.10/utils/gss
 +        uint32_t        gid;
 +        uint32_t        svc;
 +        uint64_t        nid;
-+        uint64_t        pag;
 +        char            obd[64];
 +};
 +
@@ -3224,6 +4027,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.h nfs-utils-1.0.10/utils/gss
 +};
 +
 +int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen);
++void cleanup_mapping(void);
 +int lookup_mapping(char *princ, uint64_t nid, uid_t *uid);
 +lnet_nid_t libcfs_str2nid(char *str);
 +
@@ -3237,9 +4041,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/lsupport.h nfs-utils-1.0.10/utils/gss
 +#define LNET_MKNET(typ,num)    ((((uint32_t)(typ))<<16)|((uint32_t)(num)))
 +
 +#endif /* __LIBCFS_H__ */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/Makefile.am nfs-utils-1.0.10/utils/gssd/Makefile.am
---- nfs-utils-1.0.10.orig/utils/gssd/Makefile.am       2006-11-15 21:26:08.000000000 -0700
-+++ nfs-utils-1.0.10/utils/gssd/Makefile.am    2006-12-15 15:11:52.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/Makefile.am nfs-utils-1.0.10.lustre/utils/gssd/Makefile.am
+--- nfs-utils-1.0.10/utils/gssd/Makefile.am    2007-05-15 13:02:26.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/Makefile.am     2007-05-15 13:00:53.000000000 -0600
 @@ -1,17 +1,11 @@
  ## Process this file with automake to produce Makefile.in
  
@@ -3345,9 +4149,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/Makefile.am nfs-utils-1.0.10/utils/gs
 -          rm -f $(RPCPREFIX)$$inst ; \
 -        done)
 -
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c nfs-utils-1.0.10/utils/gssd/svcgssd.c
---- nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c 2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/svcgssd.c      2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/svcgssd.c nfs-utils-1.0.10.lustre/utils/gssd/svcgssd.c
+--- nfs-utils-1.0.10/utils/gssd/svcgssd.c      2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/svcgssd.c       2007-05-15 13:01:35.000000000 -0600
 @@ -43,7 +43,6 @@
  #include <sys/types.h>
  #include <sys/stat.h>
@@ -3391,7 +4195,15 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c nfs-utils-1.0.10/utils/gssd
  /*
   * mydaemon creates a pipe between the partent and child
   * process. The parent process will wait until the
-@@ -165,8 +186,8 @@ main(int argc, char *argv[])
+@@ -139,6 +160,7 @@ void
+ sig_die(int signal)
+ {
+       /* destroy krb5 machine creds */
++      cleanup_mapping();
+       printerr(1, "exiting on signal %d\n", signal);
+       exit(1);
+ }
+@@ -165,8 +187,8 @@ main(int argc, char *argv[])
        int get_creds = 1;
        int fg = 0;
        int verbosity = 0;
@@ -3401,7 +4213,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c nfs-utils-1.0.10/utils/gssd
        extern char *optarg;
        char *progname;
  
-@@ -181,8 +202,13 @@ main(int argc, char *argv[])
+@@ -181,8 +203,13 @@ main(int argc, char *argv[])
                        case 'v':
                                verbosity++;
                                break;
@@ -3417,7 +4229,7 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c nfs-utils-1.0.10/utils/gssd
                                break;
                        default:
                                usage(argv[0]);
-@@ -196,27 +222,18 @@ main(int argc, char *argv[])
+@@ -196,27 +223,18 @@ main(int argc, char *argv[])
                progname = argv[0];
  
        initerr(progname, verbosity, fg);
@@ -3450,12 +4262,16 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c nfs-utils-1.0.10/utils/gssd
                  printerr(0, "unable to obtain root (machine) credentials\n");
                  printerr(0, "do you have a keytab entry for "
                            "nfs/<your.host>@<YOUR.REALM> in "
-@@ -225,9 +242,18 @@ main(int argc, char *argv[])
+@@ -225,9 +243,23 @@ main(int argc, char *argv[])
        }
  
        if (!fg)
 +              mydaemon(0, 0);
 +
++      /*
++       * XXX: There is risk of memory leak for missing call
++       *      cleanup_mapping() for SIGKILL and SIGSTOP.
++       */
 +      signal(SIGINT, sig_die);
 +      signal(SIGTERM, sig_die);
 +      signal(SIGHUP, sig_hup);
@@ -3467,12 +4283,13 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.c nfs-utils-1.0.10/utils/gssd
 +      gssd_init_unique(GSSD_SVC);
 +
 +      svcgssd_run();
++      cleanup_mapping();
        printerr(0, "gssd_run returned!\n");
        abort();
  }
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.h nfs-utils-1.0.10/utils/gssd/svcgssd.h
---- nfs-utils-1.0.10.orig/utils/gssd/svcgssd.h 2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/svcgssd.h      2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/svcgssd.h nfs-utils-1.0.10.lustre/utils/gssd/svcgssd.h
+--- nfs-utils-1.0.10/utils/gssd/svcgssd.h      2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/svcgssd.h       2007-05-15 13:01:35.000000000 -0600
 @@ -35,9 +35,20 @@
  #include <sys/queue.h>
  #include <gssapi/gssapi.h>
@@ -3497,9 +4314,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd.h nfs-utils-1.0.10/utils/gssd
 +#define LUSTRE_ROOT_NAMELEN                   11
  
  #endif /* _RPC_SVCGSSD_H_ */
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd_main_loop.c nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c
---- nfs-utils-1.0.10.orig/utils/gssd/svcgssd_main_loop.c       2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c    2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c nfs-utils-1.0.10.lustre/utils/gssd/svcgssd_main_loop.c
+--- nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c    2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/svcgssd_main_loop.c     2007-05-15 13:01:35.000000000 -0600
 @@ -46,46 +46,66 @@
  #include "svcgssd.h"
  #include "err_util.h"
@@ -3588,9 +4405,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd_main_loop.c nfs-utils-1.0.10/
                }
        }
  }
-diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd_proc.c nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c
---- nfs-utils-1.0.10.orig/utils/gssd/svcgssd_proc.c    2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c 2006-12-15 15:12:23.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c nfs-utils-1.0.10.lustre/utils/gssd/svcgssd_proc.c
+--- nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c 2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/gssd/svcgssd_proc.c  2007-05-15 13:01:35.000000000 -0600
 @@ -35,7 +35,6 @@
  
  #include <sys/param.h>
@@ -3924,9 +4741,9 @@ diff -rup nfs-utils-1.0.10.orig/utils/gssd/svcgssd_proc.c nfs-utils-1.0.10/utils
  
  out_err:
        if (ctx != GSS_C_NO_CONTEXT)
-diff -rup nfs-utils-1.0.10.orig/utils/Makefile.am nfs-utils-1.0.10/utils/Makefile.am
---- nfs-utils-1.0.10.orig/utils/Makefile.am    2006-08-07 00:40:50.000000000 -0600
-+++ nfs-utils-1.0.10/utils/Makefile.am 2006-12-15 15:11:52.000000000 -0700
+diff -rNup nfs-utils-1.0.10/utils/Makefile.am nfs-utils-1.0.10.lustre/utils/Makefile.am
+--- nfs-utils-1.0.10/utils/Makefile.am 2006-08-07 00:40:50.000000000 -0600
++++ nfs-utils-1.0.10.lustre/utils/Makefile.am  2007-05-15 13:00:53.000000000 -0600
 @@ -2,31 +2,6 @@
  
  OPTDIRS =