]> git.pld-linux.org Git - packages/nfs-utils.git/commitdiff
- updated to latest patchset
authorJan Rękorajski <baggins@pld-linux.org>
Tue, 14 Aug 2007 14:12:41 +0000 (14:12 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    nfs-utils-CITI_NFS4.patch -> 1.5

nfs-utils-CITI_NFS4.patch

index 3e2ec9faede0585f67213877884f96b0023063a7..66ea292e980b923fe61e2da85a0459a6f41c9048 100644 (file)
-Add secinfo processing.
 
-From: Fred Isaman <iisaman@citi.umich.edu>
 
-Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
+The complete set of CITI nfs-utils patches rolled into one patch.
 
-Add secinfo processing.
----
-
- support/include/nfslib.h  |    6 ++
- support/nfs/exports.c     |  145 ++++++++++++++++++++++++++++++++++++++++++++-
- utils/exportfs/exportfs.c |    3 +
- utils/mountd/cache.c      |   14 ++++
- 4 files changed, 164 insertions(+), 4 deletions(-)
-
-Try to use kernel function to determine supported Kerberos enctypes.
+Changes since 1.0.11-CITI_NFS4_ALL-1:
 
-From: Kevin Coffman <kwc@citi.umich.edu>
+ * Update to nfs-utils-1.1.0
 
-Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
+ * Include patches from git not yet in a release:
+   - Fix mount error messages
 
-This patch replaces a hard-coded list with a function to obtain
-the Kerberos encryption types that the kernel's rpcsec_gss code
-can support.  Defaults to old behavior if kernel does not supply
-information.
----
-
- utils/gssd/gssd.c      |    2 
- utils/gssd/krb5_util.c |  228 +++++++++++++++++++++++++++++++++++++-----------
- utils/gssd/krb5_util.h |    2 
- 3 files changed, 182 insertions(+), 50 deletions(-)
+ * Update gssd usage message to include new -n option.
 
-Add EXPERIMENTAL support for non-DES encryption types.
+ * Patches from Bruce Fields to clean up compile warning, and
+   move pseudoflavor code to a common location
 
-From: Kevin Coffman <kwc@citi.umich.edu>
+ * Patch from Bruce Fields and Fred Isaman that adds support
+   to exportfs for reading a sec= option and sending server
+   security data through cache via
+   "... secinfo n flavor1 flag1 ... flavorN flagN".
 
-Signed-off-by: Kevin Coffman <kwc@citi.umich.edu>
 
-Adds EXPERIMENTAL support for non-DES encryption types.  Sends a new
-format of context information to the kernel.
-(Requires kernel support to do anything useful.)
 ---
 
- utils/gssd/context.h       |    6 +
- utils/gssd/context_lucid.c |  391 ++++++++++++++++++++++++++++++++++++++++++--
- utils/gssd/context_mit.c   |  254 +++++++++++++++++++++++++----
- 3 files changed, 603 insertions(+), 48 deletions(-)
+ nfs-utils-1.1.0-kwc/support/include/nfslib.h        |   10 +
+ nfs-utils-1.1.0-kwc/support/include/pseudoflavors.h |   17 ++
+ nfs-utils-1.1.0-kwc/support/nfs/exports.c           |  158 ++++++++++++++++++--
+ nfs-utils-1.1.0-kwc/utils/exportfs/exportfs.c       |    1 
+ nfs-utils-1.1.0-kwc/utils/gssd/gssd.c               |    2 
+ nfs-utils-1.1.0-kwc/utils/mount/mount.c             |   40 ++++-
+ nfs-utils-1.1.0-kwc/utils/mount/nfs4_mount.h        |   12 -
+ nfs-utils-1.1.0-kwc/utils/mount/nfs4mount.c         |   27 ---
+ nfs-utils-1.1.0-kwc/utils/mountd/cache.c            |   21 ++
+ 10 files changed, 240 insertions(+), 49 deletions(-)
 
-diff --git a/support/include/nfslib.h b/support/include/nfslib.h
-index c085029..6d7743d 100644
---- a/support/include/nfslib.h
-+++ b/support/include/nfslib.h
-@@ -57,6 +57,9 @@ enum cle_maptypes {
- #define       _PATH_PROC_EXPORTS_ALT  "/proc/fs/nfsd/exports"
- #endif
+diff -puN utils/mount/mount.c~CITI_NFS4_ALL utils/mount/mount.c
+--- nfs-utils-1.1.0/utils/mount/mount.c~CITI_NFS4_ALL  2007-06-22 10:51:38.885022000 -0400
++++ nfs-utils-1.1.0-kwc/utils/mount/mount.c    2007-06-22 10:52:04.954241000 -0400
+@@ -285,22 +285,49 @@ static void parse_opts (const char *opti
+       }
+ }
  
-+#define SECFLAVOR_COUNT 7
-+extern char *secflavor_name[SECFLAVOR_COUNT];
+-static void mount_error(char *node)
++static void mount_error(char *mntpnt, char *node)
+ {
+       switch(errno) {
+               case ENOTDIR:
+-                      fprintf(stderr, "%s: mount point %s is not a directory\n", progname, node);
++                      fprintf(stderr, "%s: mount point %s is not a directory\n", 
++                              progname, mntpnt);
+                       break;
+               case EBUSY:
+-                      fprintf(stderr, "%s: %s is already mounted or busy\n", progname, node);
++                      fprintf(stderr, "%s: %s is already mounted or busy\n", 
++                              progname, mntpnt);
+                       break;
+               case ENOENT:
+-                      fprintf(stderr, "%s: mount point %s does not exist\n", progname, node);
++                      if (node) {
++                              fprintf(stderr, "%s: %s failed, reason given by server: %s\n",
++                                      progname, node, strerror(errno));
++                      } else
++                              fprintf(stderr, "%s: mount point %s does not exist\n", 
++                                      progname, mntpnt);
+                       break;
+               default:
+                       fprintf(stderr, "%s: %s\n", progname, strerror(errno));
+       }
+ }
++static int chk_mountpoint(char *mount_point)
++{
++      struct stat sb;
 +
- /*
-  * Data related to a single exports entry as returned by getexportent.
-  * FIXME: export options should probably be parsed at a later time to
-@@ -83,6 +86,8 @@ struct exportent {
-       int             e_fslocmethod;
-       char *          e_fslocdata;
-       char *          e_uuid;
-+      int             e_secinfo_order[SECFLAVOR_COUNT+1];
-+      int             e_secinfo_flags[SECFLAVOR_COUNT];
- };
++      if (stat(mount_point, &sb) < 0){
++              mount_error(mount_point, NULL);
++              return 1;
++      }
++      if (S_ISDIR(sb.st_mode) == 0){
++              errno = ENOTDIR;
++              mount_error(mount_point, NULL);
++              return 1;
++      }
++      if (access(mount_point, X_OK) < 0) {
++              mount_error(mount_point, NULL);
++              return 1;
++      }
++
++      return 0;
++}
  
- struct rmtabent {
-@@ -96,6 +101,7 @@ struct rmtabent {
-  */
- void                  setexportent(char *fname, char *type);
- struct exportent *    getexportent(int,int);
-+void                  secinfo_show(FILE *fp, struct exportent *ep);
- void                  putexportent(struct exportent *xep);
- void                  endexportent(void);
- struct exportent *    mkexportent(char *hname, char *path, char *opts);
-diff --git a/support/nfs/exports.c b/support/nfs/exports.c
-index 294e1c9..af9ab2f 100644
---- a/support/nfs/exports.c
-+++ b/support/nfs/exports.c
-@@ -51,6 +51,10 @@ static int  parsenum(char **cpp);
- static int    parsenum(char **cpp);
- static void   freesquash(void);
- static void   syntaxerr(char *msg);
-+static unsigned int parse_flavors(char *str, struct exportent *ep);
-+static int    secinfo_default(struct exportent *ep);
-+static void   setflags(int mask, unsigned int *ap, struct exportent *ep);
-+static void   clearflags(int mask, unsigned int *ap, struct exportent *ep);
+ extern u_short getport(
+       struct sockaddr_in *saddr,
+@@ -508,6 +535,9 @@ int main(int argc, char *argv[])
+           }
+       }
  
- void
- setexportent(char *fname, char *type)
-@@ -102,6 +106,7 @@ getexportent(int fromkernel, int fromexp
++      if (chk_mountpoint(mount_point))
++              exit(EX_FAIL);
++
+       if (nfs_mount_vers == 4)
+               mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
+       else {
+@@ -538,7 +568,7 @@ int main(int argc, char *argv[])
+                                          mount_opts);
+               if (mnt_err) {
+-                      mount_error(mount_point);
++                      mount_error(mount_point, spec);
+                       exit(EX_FAIL);
+               }
+       }
+diff -puN utils/gssd/gssd.c~CITI_NFS4_ALL utils/gssd/gssd.c
+--- nfs-utils-1.1.0/utils/gssd/gssd.c~CITI_NFS4_ALL    2007-06-22 10:51:53.782368000 -0400
++++ nfs-utils-1.1.0-kwc/utils/gssd/gssd.c      2007-06-22 10:51:56.521019000 -0400
+@@ -81,7 +81,7 @@ sig_hup(int signal)
+ static void
+ usage(char *progname)
+ {
+-      fprintf(stderr, "usage: %s [-f] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
++      fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
+               progname);
+       exit(1);
+ }
+diff -puN /dev/null support/include/pseudoflavors.h
+--- /dev/null  2007-06-21 19:03:53.875366737 -0400
++++ nfs-utils-1.1.0-kwc/support/include/pseudoflavors.h        2007-06-22 10:52:22.335293000 -0400
+@@ -0,0 +1,17 @@
++#define RPC_AUTH_GSS_KRB5       390003
++#define RPC_AUTH_GSS_KRB5I      390004
++#define RPC_AUTH_GSS_KRB5P      390005
++#define RPC_AUTH_GSS_LKEY       390006
++#define RPC_AUTH_GSS_LKEYI      390007
++#define RPC_AUTH_GSS_LKEYP      390008
++#define RPC_AUTH_GSS_SPKM       390009
++#define RPC_AUTH_GSS_SPKMI      390010
++#define RPC_AUTH_GSS_SPKMP      390011
++
++struct flav_info {
++      char    *flavour;
++      int     fnum;
++};
++
++extern struct flav_info flav_map[];
++extern const int flav_map_size;
+diff -puN support/nfs/exports.c~CITI_NFS4_ALL support/nfs/exports.c
+--- nfs-utils-1.1.0/support/nfs/exports.c~CITI_NFS4_ALL        2007-06-22 10:52:16.682999000 -0400
++++ nfs-utils-1.1.0-kwc/support/nfs/exports.c  2007-06-22 10:52:40.578175000 -0400
+@@ -30,10 +30,29 @@
+ #include "xmalloc.h"
+ #include "xlog.h"
+ #include "xio.h"
++#include "pseudoflavors.h"
+ #define EXPORT_DEFAULT_FLAGS  \
+   (NFSEXP_READONLY|NFSEXP_ROOTSQUASH|NFSEXP_GATHERED_WRITES|NFSEXP_NOSUBTREECHECK)
++struct flav_info flav_map[] = {
++      { "krb5",       RPC_AUTH_GSS_KRB5       },
++      { "krb5i",      RPC_AUTH_GSS_KRB5I      },
++      { "krb5p",      RPC_AUTH_GSS_KRB5P      },
++      { "lipkey",     RPC_AUTH_GSS_LKEY       },
++      { "lipkey-i",   RPC_AUTH_GSS_LKEYI      },
++      { "lipkey-p",   RPC_AUTH_GSS_LKEYP      },
++      { "spkm3",      RPC_AUTH_GSS_SPKM       },
++      { "spkm3i",     RPC_AUTH_GSS_SPKMI      },
++      { "spkm3p",     RPC_AUTH_GSS_SPKMP      },
++      { "unix",       AUTH_UNIX               },
++      { "sys",        AUTH_SYS                },
++      { "null",       AUTH_NULL               },
++      { "none",       AUTH_NONE               },
++};
++
++const int flav_map_size = sizeof(flav_map)/sizeof(flav_map[0]);
++
+ int export_errno;
+ static char   *efname = NULL;
+@@ -100,6 +119,7 @@ getexportent(int fromkernel, int fromexp
                def_ee.e_mountpoint = NULL;
                def_ee.e_fslocmethod = FSLOC_NONE;
                def_ee.e_fslocdata = NULL;
-+              def_ee.e_secinfo_order[0] = -1;
++              def_ee.e_secinfo[0].flav = NULL;
                def_ee.e_nsquids = 0;
                def_ee.e_nsqgids = 0;
  
-@@ -182,6 +187,19 @@ getexportent(int fromkernel, int fromexp
+@@ -179,6 +199,27 @@ getexportent(int fromkernel, int fromexp
+       return &ee;
  }
  
- void
-+secinfo_show(FILE *fp, struct exportent *ep)
++void secinfo_show(FILE *fp, struct exportent *ep)
 +{
-+      int *p1, *p2;
-+      for (p1=ep->e_secinfo_order; *p1>=0; p1=p2) {
-+              fprintf(fp, ",sec=%s", secflavor_name[*p1]);
-+              for (p2=p1+1; (*p2>=0) && (ep->e_secinfo_flags[*p1]==ep->e_secinfo_flags[*p2]); p2++) {
-+                      fprintf(fp, ":%s", secflavor_name[*p2]);
++      struct sec_entry *p1, *p2;
++      int flags;
++
++      for (p1=ep->e_secinfo; p1->flav; p1=p2) {
++
++              fprintf(fp, ",sec=%s", p1->flav->flavour);
++              for (p2=p1+1; (p2->flav != NULL) && (p1->flags == p2->flags);
++                                                              p2++) {
++                      fprintf(fp, ":%s", p2->flav->flavour);
 +              }
-+              fprintf(fp, ",%s", (ep->e_secinfo_flags[*p1] & NFSEXP_READONLY)? "ro" : "rw");
++              flags = p1->flags;
++              fprintf(fp, ",%s", (flags & NFSEXP_READONLY) ? "ro" : "rw");
++              fprintf(fp, ",%sroot_squash", (flags & NFSEXP_ROOTSQUASH)?
++                              "" : "no_");
++              fprintf(fp, ",%sall_squash", (flags & NFSEXP_ALLSQUASH)?
++                              "" : "no_");
 +      }
 +}
 +
-+void
+ void
  putexportent(struct exportent *ep)
  {
-       FILE    *fp;
-@@ -199,7 +217,6 @@ putexportent(struct exportent *ep)
-                       fprintf(fp, "%c", esc[i]);
-       fprintf(fp, "\t%s(", ep->e_hostname);
--      fprintf(fp, "%s,", (ep->e_flags & NFSEXP_READONLY)? "ro" : "rw");
-       fprintf(fp, "%ssync,", (ep->e_flags & NFSEXP_ASYNC)? "a" : "");
-       fprintf(fp, "%swdelay,", (ep->e_flags & NFSEXP_GATHERED_WRITES)?
-                               "" : "no_");
-@@ -276,7 +293,9 @@ #endif
+@@ -259,7 +300,9 @@ putexportent(struct exportent *ep)
                        else
                                fprintf(fp, "%d,", id[i]);
        }
@@ -139,1298 +222,350 @@ index 294e1c9..af9ab2f 100644
  }
  
  void
-@@ -325,6 +344,7 @@ mkexportent(char *hname, char *path, cha
+@@ -307,6 +350,7 @@ mkexportent(char *hname, char *path, cha
        ee.e_mountpoint = NULL;
        ee.e_fslocmethod = FSLOC_NONE;
        ee.e_fslocdata = NULL;
-+      ee.e_secinfo_order[0] = -1;
++      ee.e_secinfo[0].flav = NULL;
        ee.e_nsquids = 0;
        ee.e_nsqgids = 0;
        ee.e_uuid = NULL;
-@@ -376,6 +396,9 @@ parseopts(char *cp, struct exportent *ep
-       int     had_subtree_opt = 0;
-       char    *flname = efname?efname:"command line";
-       int     flline = efp?efp->x_line:0;
-+      int     *p;
-+      unsigned int active = 0;
-+      int secmask = NFSEXP_READONLY;  /* options that can vary per flavor */
-       squids = ep->e_squids; nsquids = ep->e_nsquids;
-       sqgids = ep->e_sqgids; nsqgids = ep->e_nsqgids;
-@@ -398,9 +421,9 @@ parseopts(char *cp, struct exportent *ep
-               /* process keyword */
-               if (strcmp(opt, "ro") == 0)
--                      ep->e_flags |= NFSEXP_READONLY;
-+                      setflags(NFSEXP_READONLY, &active, ep);
-               else if (strcmp(opt, "rw") == 0)
--                      ep->e_flags &= ~NFSEXP_READONLY;
-+                      clearflags(NFSEXP_READONLY, &active, ep);
-               else if (!strcmp(opt, "secure"))
-                       ep->e_flags &= ~NFSEXP_INSECURE_PORT;
-               else if (!strcmp(opt, "insecure"))
-@@ -522,6 +545,10 @@ #endif
-               } else if (strncmp(opt, "replicas=", 9) == 0) {
-                       ep->e_fslocmethod = FSLOC_REPLICA;
-                       ep->e_fslocdata = strdup(opt+9);
-+              } else if (strncmp(opt, "sec=", 4) == 0) {
-+                      active = parse_flavors(opt+4, ep);
-+                      if (!active)
-+                              goto bad_option;
-               } else {
-                       xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
-                                       flname, flline, opt);
-@@ -533,6 +560,12 @@ #endif
-                       cp++;
-       }
-+      if (!active)
-+              active = secinfo_default(ep);
-+      for (p=ep->e_secinfo_order; *p>=0; p++)
-+              ep->e_secinfo_flags[*p] |= (ep->e_flags & ~secmask);
-+      /* If did not use sec= option, ensure e_flags is backward compatible */
-+      ep->e_flags = ep->e_secinfo_flags[ep->e_secinfo_order[0]];
-       ep->e_squids = squids;
-       ep->e_sqgids = sqgids;
-       ep->e_nsquids = nsquids;
-@@ -663,3 +696,107 @@ syntaxerr(char *msg)
-                       efname, efp?efp->x_line:0, msg);
+@@ -350,18 +394,110 @@ static int valid_uuid(char *uuid)
  }
  
-+char *secflavor_name[SECFLAVOR_COUNT] = { "sys",
-+                                        "krb5",
-+                                        "krb5i",
-+                                        "krb5p",
-+                                        "spkm3",
-+                                        "spkm3i",
-+                                        "spkm3p"
-+};
-+
-+static void
-+secinfo_addflavor(int bit, struct exportent *ep)
+ /*
++ * Append the given flavor to the exportent's e_secinfo array, or
++ * do nothing if it's already there.  Returns the index of flavor
++ * in the resulting array in any case.
++ */
++static int secinfo_addflavor(struct flav_info *flav, struct exportent *ep)
 +{
-+      int *p;
-+      for (p=ep->e_secinfo_order; *p>=0; p++) {
-+              if (*p == bit)
-+                      return;
++      struct sec_entry *p;
++
++      for (p=ep->e_secinfo; p->flav; p++) {
++              if (p->flav == flav)
++                      return p - ep->e_secinfo;
 +      }
-+      *p++ = bit;
-+      *p = -1;
-+      ep->e_secinfo_flags[bit] = 0;
++      if (p - ep->e_secinfo >= SECFLAVOR_COUNT) {
++              xlog(L_ERROR, "more than %d security flavors on an export\n",
++                      SECFLAVOR_COUNT);
++              return -1;
++      }
++      p->flav = flav;
++      p->flags = ep->e_flags;
++      (p+1)->flav = NULL;
++      return p - ep->e_secinfo;
 +}
 +
-+static int
-+secinfo_nameindex(char *name)
++static struct flav_info *find_flavor(char *name)
 +{
-+      int i;
-+      for (i=0; i<SECFLAVOR_COUNT; i++) {
-+              if (strcmp(secflavor_name[i], name) == 0)
-+                      return i;
-+      }
-+      return -1;
++      struct flav_info *flav;
++      for (flav = flav_map; flav < flav_map + flav_map_size; flav++)
++              if (strcmp(flav->flavour, name) == 0)
++                      return flav;
++      return NULL;
 +}
 +
 +/* @str is a colon seperated list of security flavors.  Their order
 + * is recorded in @ep, and a bitmap corresponding to the list is returned.
 + * A zero return indicates an error.
 + */
-+static unsigned int
-+parse_flavors(char *str, struct exportent *ep)
++static unsigned int parse_flavors(char *str, struct exportent *ep)
 +{
 +      unsigned int out=0;
 +      char *flavor;
-+      int bit; 
++      int bit;
 +
 +      while ( (flavor=strsep(&str, ":")) ) {
-+              bit = secinfo_nameindex(flavor);
-+              if (bit == -1) {
++              struct flav_info *flav = find_flavor(flavor);
++              if (flav == NULL) {
 +                      xlog(L_ERROR, "unknown flavor %s\n", flavor);
 +                      return 0;
 +              }
++              bit = secinfo_addflavor(flav, ep);
++              if (bit < 0)
++                      return 0;
 +              out |= 1<<bit;
-+              secinfo_addflavor(bit, ep);
 +      }
 +      return out;
 +}
 +
-+/* Determine a default security flavor based on ep->e_hostname. */
-+static int
-+secinfo_default(struct exportent *ep)
-+{
-+      int i=-1;
-+      if (strncmp(ep->e_hostname, "gss/", 4) == 0) {
-+              i = secinfo_nameindex(ep->e_hostname + 4);
-+              if (i < 0)
-+                      xlog(L_WARNING, "unknown flavor %s\n", ep->e_hostname);
-+      }
-+      /* Default to auth_sys */
-+      if (i < 0)
-+              i = secinfo_nameindex("sys");
-+      secinfo_addflavor(i, ep);
-+      return 1<<i;
-+}
-+
 +/* Sets the bits in @mask for the appropriate security flavor flags. */
-+static void
-+setflags(int mask, unsigned int *ap, struct exportent *ep)
++static void setflags(int mask, unsigned int active, struct exportent *ep)
 +{
-+      int active, flavor=0;
-+      if (!*ap)
-+              *ap = secinfo_default(ep);
-+      active = *ap;
++      int bit=0;
++
++      ep->e_flags |= mask;
++
 +      while (active) {
 +              if (active & 1)
-+                      ep->e_secinfo_flags[flavor] |= mask;
-+              flavor++;
++                      ep->e_secinfo[bit].flags |= mask;
++              bit++;
 +              active >>= 1;
 +      }
 +}
 +
 +/* Clears the bits in @mask for the appropriate security flavor flags. */
-+static void
-+clearflags(int mask, unsigned int *ap, struct exportent *ep)
++static void clearflags(int mask, unsigned int active, struct exportent *ep)
 +{
-+      int active, flavor=0;
-+      if (!*ap)
-+              *ap = secinfo_default(ep);
-+      active = *ap;
++      int bit=0;
++
++      ep->e_flags &= ~mask;
++
 +      while (active) {
 +              if (active & 1)
-+                      ep->e_secinfo_flags[flavor] &= ~mask;
-+              flavor++;
++                      ep->e_secinfo[bit].flags &= ~mask;
++              bit++;
 +              active >>= 1;
 +      }
 +}
-diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
-index 22e13a3..30732b8 100644
---- a/utils/exportfs/exportfs.c
-+++ b/utils/exportfs/exportfs.c
-@@ -376,10 +376,12 @@ dump(int verbose)
-                               continue;
-                       }
-                       c = '(';
-+                      /*
-                       if (ep->e_flags & NFSEXP_READONLY)
-                               c = dumpopt(c, "ro");
-                       else
-                               c = dumpopt(c, "rw");
-+                      */
-                       if (ep->e_flags & NFSEXP_ASYNC)
-                               c = dumpopt(c, "async");
-                       if (ep->e_flags & NFSEXP_GATHERED_WRITES)
-@@ -433,6 +435,7 @@ #ifdef DEBUG
-                               break;
- #endif
-                       }
-+                      secinfo_show(stdout, ep);
-                       printf("%c\n", (c != '(')? ')' : ' ');
-               }
-       }
-diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
-index 5f0d12a..78a8f75 100644
---- a/utils/mountd/cache.c
-+++ b/utils/mountd/cache.c
-@@ -445,6 +445,19 @@ static void write_fsloc(FILE *f, struct 
-       release_replicas(servers);
- }
-+static void write_secinfo(FILE *f, struct exportent *ep)
-+{
-+      int *p;
-+      qword_print(f, "secinfo");
-+      for (p=ep->e_secinfo_order; *p>=0; p++)
-+              ; /* Do nothing */
-+      qword_printint(f, p - ep->e_secinfo_order);
-+      for (p=ep->e_secinfo_order; *p>=0; p++) {
-+              qword_print(f, secflavor_name[*p]);
-+              qword_printint(f, ep->e_secinfo_flags[*p]);
-+      }
-+}
 +
- static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp)
++/* options that can vary per flavor: */
++#define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
++                                      | NFSEXP_ALLSQUASH)
++
++/*
+  * Parse option string pointed to by cp and set mount options accordingly.
+  */
+ static int
+ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
  {
-       qword_print(f, domain);
-@@ -466,6 +479,7 @@ static int dump_to_cache(FILE *f, char *
-                       qword_printhex(f, exp->e_uuid, 16);
-               }
- #endif
-+              write_secinfo(f, exp);
-       }
-       return qword_eol(f);
- }
-diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
-index 08a6c10..44afdd0 100644
---- a/utils/gssd/gssd.c
-+++ b/utils/gssd/gssd.c
-@@ -162,6 +162,8 @@ #endif
-       /* Process keytab file and get machine credentials */
-       if (root_uses_machine_creds)
-               gssd_refresh_krb5_machine_creds();
-+      /* Determine Kerberos information from the kernel */
-+      gssd_obtain_kernel_krb5_info();
++      struct sec_entry *p;
+       int     had_subtree_opt = 0;
+       char    *flname = efname?efname:"command line";
+       int     flline = efp?efp->x_line:0;
++      unsigned int active = 0;
  
-       gssd_run();
-       printerr(0, "gssd_run returned!\n");
-diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
-index 096f6cf..96e91ae 100644
---- a/utils/gssd/krb5_util.c
-+++ b/utils/gssd/krb5_util.c
-@@ -97,6 +97,7 @@ #endif
- #include "config.h"
- #include <sys/param.h>
- #include <rpc/rpc.h>
-+#include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
-@@ -105,6 +106,7 @@ #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dirent.h>
-+#include <fcntl.h>
- #include <errno.h>
- #include <time.h>
- #include <gssapi/gssapi.h>
-@@ -123,6 +125,10 @@ #include "krb5_util.h"
- /* Global list of principals/cache file names for machine credentials */
- struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
+       squids = ep->e_squids; nsquids = ep->e_nsquids;
+       sqgids = ep->e_sqgids; nsqgids = ep->e_nsqgids;
+-
+       if (!cp)
+               goto out;
  
-+/* Encryption types supported by the kernel rpcsec_gss code */
-+int num_krb5_enctypes = 0;
-+krb5_enctype *krb5_enctypes = NULL;
-+
- /*==========================*/
- /*===  Internal routines ===*/
- /*==========================*/
-@@ -256,56 +262,6 @@ gssd_find_existing_krb5_ccache(uid_t uid
- }
+@@ -380,9 +516,9 @@ parseopts(char *cp, struct exportent *ep
  
+               /* process keyword */
+               if (strcmp(opt, "ro") == 0)
+-                      ep->e_flags |= NFSEXP_READONLY;
++                      setflags(NFSEXP_READONLY, active, ep);
+               else if (strcmp(opt, "rw") == 0)
+-                      ep->e_flags &= ~NFSEXP_READONLY;
++                      clearflags(NFSEXP_READONLY, active, ep);
+               else if (!strcmp(opt, "secure"))
+                       ep->e_flags &= ~NFSEXP_INSECURE_PORT;
+               else if (!strcmp(opt, "insecure"))
+@@ -404,13 +540,13 @@ parseopts(char *cp, struct exportent *ep
+               else if (!strcmp(opt, "no_wdelay"))
+                       ep->e_flags &= ~NFSEXP_GATHERED_WRITES;
+               else if (strcmp(opt, "root_squash") == 0)
+-                      ep->e_flags |= NFSEXP_ROOTSQUASH;
++                      setflags(NFSEXP_ROOTSQUASH, active, ep);
+               else if (!strcmp(opt, "no_root_squash"))
+-                      ep->e_flags &= ~NFSEXP_ROOTSQUASH;
++                      clearflags(NFSEXP_ROOTSQUASH, active, ep);
+               else if (strcmp(opt, "all_squash") == 0)
+-                      ep->e_flags |= NFSEXP_ALLSQUASH;
++                      setflags(NFSEXP_ALLSQUASH, active, ep);
+               else if (strcmp(opt, "no_all_squash") == 0)
+-                      ep->e_flags &= ~NFSEXP_ALLSQUASH;
++                      clearflags(NFSEXP_ALLSQUASH, active, ep);
+               else if (strcmp(opt, "subtree_check") == 0) {
+                       had_subtree_opt = 1;
+                       ep->e_flags &= ~NFSEXP_NOSUBTREECHECK;
+@@ -498,6 +634,10 @@ bad_option:
+               } else if (strncmp(opt, "replicas=", 9) == 0) {
+                       ep->e_fslocmethod = FSLOC_REPLICA;
+                       ep->e_fslocdata = strdup(opt+9);
++              } else if (strncmp(opt, "sec=", 4) == 0) {
++                      active = parse_flavors(opt+4, ep);
++                      if (!active)
++                              goto bad_option;
+               } else {
+                       xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
+                                       flname, flline, opt);
+@@ -509,6 +649,8 @@ bad_option:
+                       cp++;
+       }
  
--#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
--/*
-- * this routine obtains a credentials handle via gss_acquire_cred()
-- * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
-- * types negotiated.
-- *
-- * XXX Should call some function to determine the enctypes supported
-- * by the kernel. (Only need to do that once!)
-- *
-- * Returns:
-- *    0 => all went well
-- *     -1 => there was an error
-- */
--
--int
--limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
--{
--      u_int maj_stat, min_stat;
--      gss_cred_id_t credh;
--      gss_OID_set_desc  desired_mechs;
--      krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
--      int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
--
--      /* We only care about getting a krb5 cred */
--      desired_mechs.count = 1;
--      desired_mechs.elements = &krb5oid;
--
--      maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
--                                  &desired_mechs, GSS_C_INITIATE,
--                                  &credh, NULL, NULL);
--
--      if (maj_stat != GSS_S_COMPLETE) {
--              pgsserr("gss_acquire_cred",
--                      maj_stat, min_stat, &krb5oid);
--              return -1;
--      }
--
--      maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
--                                           num_enctypes, &enctypes);
--      if (maj_stat != GSS_S_COMPLETE) {
--              pgsserr("gss_set_allowable_enctypes",
--                      maj_stat, min_stat, &krb5oid);
--              return -1;
--      }
--      sec->cred = credh;
--
--      return 0;
--}
--#endif        /* HAVE_SET_ALLOWABLE_ENCTYPES */
--
- /*
-  * Obtain credentials via a key in the keytab given
-  * a keytab handle and a gssd_k5_kt_princ structure.
-@@ -609,6 +565,56 @@ #else
++      for (p = ep->e_secinfo; p->flav; p++)
++              p->flags |= ep->e_flags & ~NFSEXP_SECINFO_FLAGS;
+       ep->e_squids = squids;
+       ep->e_sqgids = sqgids;
+       ep->e_nsquids = nsquids;
+diff -puN utils/mount/nfs4mount.c~CITI_NFS4_ALL utils/mount/nfs4mount.c
+--- nfs-utils-1.1.0/utils/mount/nfs4mount.c~CITI_NFS4_ALL      2007-06-22 10:52:18.413097000 -0400
++++ nfs-utils-1.1.0-kwc/utils/mount/nfs4mount.c        2007-06-22 10:52:25.846889000 -0400
+@@ -36,6 +36,7 @@
+ #define nfsstat nfs_stat
  #endif
- }
-+/*
-+ * Parse the supported encryption type information
-+ */
-+static int
-+parse_enctypes(char *enctypes)
-+{
-+      int n = 0;
-+      char *curr, *comma;
-+      int i;
-+
-+      /* Just in case this ever gets called more than once */
-+      if (krb5_enctypes != NULL) {
-+              free(krb5_enctypes);
-+              krb5_enctypes = NULL;
-+              num_krb5_enctypes = 0;
-+      }
-+
-+      /* count the number of commas */
-+      for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
-+              comma = strchr(curr, ',');
-+              if (comma != NULL)
-+                      n++;
-+              else
-+                      break;
-+      }
-+      /* If no more commas and we're not at the end, there's one more value */
-+      if (*curr != '\0')
-+              n++;
-+
-+      /* Empty string, return an error */
-+      if (n == 0)
-+              return ENOENT;
-+
-+      /* Allocate space for enctypes array */
-+      if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
-+              return ENOMEM;
-+      }
-+
-+      /* Now parse each value into the array */
-+      for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
-+              krb5_enctypes[i++] = atoi(curr);
-+              comma = strchr(curr, ',');
-+              if (comma == NULL)
-+                      break;
-+      }
-+
-+      num_krb5_enctypes = n;
-+      return 0;
-+}
-+
- /*==========================*/
- /*===  External routines ===*/
- /*==========================*/
-@@ -860,3 +866,125 @@ gssd_destroy_krb5_machine_creds(void)
-       krb5_free_context(context);
- }
-+#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
-+/*
-+ * this routine obtains a credentials handle via gss_acquire_cred()
-+ * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
-+ * types negotiated.
-+ *
-+ * Returns:
-+ *    0 => all went well
-+ *     -1 => there was an error
-+ */
-+
-+int
-+limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
-+{
-+      u_int maj_stat, min_stat;
-+      gss_cred_id_t credh;
-+      gss_OID_set_desc  desired_mechs;
-+      krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC};
-+      int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
-+
-+      /* We only care about getting a krb5 cred */
-+      desired_mechs.count = 1;
-+      desired_mechs.elements = &krb5oid;
-+
-+      maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
-+                                  &desired_mechs, GSS_C_INITIATE,
-+                                  &credh, NULL, NULL);
-+
-+      if (maj_stat != GSS_S_COMPLETE) {
-+              pgsserr("gss_acquire_cred",
-+                      maj_stat, min_stat, &krb5oid);
-+              return -1;
-+      }
-+
-+      /*
-+       * If we failed for any reason to produce global
-+       * list of supported enctypes, use local default here.
-+       */
-+      if (krb5_enctypes == NULL)
-+              maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
-+                                      &krb5oid, num_enctypes, &enctypes);
-+      else
-+              maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
-+                                      &krb5oid, num_krb5_enctypes,
-+                                      krb5_enctypes);
-+      if (maj_stat != GSS_S_COMPLETE) {
-+              pgsserr("gss_set_allowable_enctypes",
-+                      maj_stat, min_stat, &krb5oid);
-+              return -1;
-+      }
-+      sec->cred = credh;
-+
-+      return 0;
-+}
-+#endif        /* HAVE_SET_ALLOWABLE_ENCTYPES */
-+
-+/*
-+ * Obtain supported enctypes from kernel.
-+ * Set defaults if info is not available.
-+ */
-+void
-+gssd_obtain_kernel_krb5_info(void)
-+{
-+      char enctype_file_name[128];
-+      char buf[1024];
-+      char enctypes[128];
-+      int nscanned;
-+      int fd;
-+      int use_default_enctypes = 0;
-+      int nbytes, numfields;
-+      char default_enctypes[] = "1,3,2";
-+      int code;
-+
-+      snprintf(enctype_file_name, sizeof(enctype_file_name),
-+               "%s/%s", pipefs_dir, "krb5_info");
-+
-+      if ((fd = open(enctype_file_name, O_RDONLY)) == -1) {
-+              printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: "
-+                       "Unable to open '%s'. Unable to determine "
-+                       "Kerberos encryption types supported by the "
-+                       "kernel; using defaults (%s).\n",
-+                       enctype_file_name, default_enctypes);
-+              use_default_enctypes = 1;
-+              goto do_the_parse;
-+      }
-+      memset(buf, 0, sizeof(buf));
-+      if ((nbytes = read(fd, buf, sizeof(buf)-1)) == -1) {
-+              printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
-+                       "Error reading Kerberos encryption type "
-+                       "information file '%s'; using defaults (%s).\n",
-+                       enctype_file_name, default_enctypes);
-+              use_default_enctypes = 1;
-+              close(fd);
-+              goto do_the_parse;
-+      }
-+      close(fd);
-+      numfields = sscanf(buf, "enctypes: %s\n%n", enctypes, &nscanned);
-+      if (numfields < 1) {
-+              printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
-+                       "error parsing Kerberos encryption type "
-+                       "information from file '%s'; using defaults (%s).\n",
-+                       enctype_file_name, default_enctypes);
-+              use_default_enctypes = 1;
-+              goto do_the_parse;
-+      }
-+      if (nbytes > nscanned) {
-+              printerr(2, "gssd_obtain_kernel_krb5_info: "
-+                       "Ignoring extra information, '%s', from '%s'\n",
-+                       buf+nscanned, enctype_file_name);
-+              goto do_the_parse;
-+      }
-+  do_the_parse:
-+      if (use_default_enctypes)
-+              strcpy(enctypes, default_enctypes);
-+
-+      if ((code = parse_enctypes(enctypes)) != 0) {
-+              printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: "
-+                       "parse_enctypes%s failed with code %d\n",
-+                       use_default_enctypes ? " (with default enctypes)" : "",
-+                       code);
-+      }
-+}
-diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
-index da04530..2af1a25 100644
---- a/utils/gssd/krb5_util.h
-+++ b/utils/gssd/krb5_util.h
-@@ -22,6 +22,8 @@ int  gssd_refresh_krb5_machine_creds(voi
- void gssd_free_krb5_machine_cred_list(char **list);
- void gssd_setup_krb5_machine_gss_ccache(char *servername);
- void gssd_destroy_krb5_machine_creds(void);
-+void gssd_obtain_kernel_krb5_info(void);
-+
  
- #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
- int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid);
-diff --git a/utils/gssd/context.h b/utils/gssd/context.h
-index 67ed3bb..68b0c11 100644
---- a/utils/gssd/context.h
-+++ b/utils/gssd/context.h
-@@ -1,5 +1,5 @@
- /*
--  Copyright (c) 2004 The Regents of the University of Michigan.
-+  Copyright (c) 2004-2006 The Regents of the University of Michigan.
-   All rights reserved.
++#include "pseudoflavors.h"
+ #include "nls.h"
+ #include "conn.h"
+ #include "xcommon.h"
+@@ -71,26 +72,6 @@ char *GSSDLCK = DEFAULT_DIR "/rpcgssd";
+ #define NFS_PORT 2049
+ #endif
  
-   Redistribution and use in source and binary forms, with or without
-@@ -36,6 +36,10 @@ #include <rpc/rpc.h>
- /* Hopefully big enough to hold any serialized context */
- #define MAX_CTX_LEN 4096
+-struct {
+-      char    *flavour;
+-      int     fnum;
+-} flav_map[] = {
+-      { "krb5",       RPC_AUTH_GSS_KRB5       },
+-      { "krb5i",      RPC_AUTH_GSS_KRB5I      },
+-      { "krb5p",      RPC_AUTH_GSS_KRB5P      },
+-      { "lipkey",     RPC_AUTH_GSS_LKEY       },
+-      { "lipkey-i",   RPC_AUTH_GSS_LKEYI      },
+-      { "lipkey-p",   RPC_AUTH_GSS_LKEYP      },
+-      { "spkm3",      RPC_AUTH_GSS_SPKM       },
+-      { "spkm3i",     RPC_AUTH_GSS_SPKMI      },
+-      { "spkm3p",     RPC_AUTH_GSS_SPKMP      },
+-      { "unix",       AUTH_UNIX               },
+-      { "sys",        AUTH_SYS                },
+-      { "null",       AUTH_NULL               },
+-      { "none",       AUTH_NONE               },
+-};
+-
+-#define FMAPSIZE              (sizeof(flav_map)/sizeof(flav_map[0]))
+ #define MAX_USER_FLAVOUR      16
  
-+/* New context format flag values */
-+#define KRB5_CTX_FLAG_INITIATOR         0x00000001
-+#define KRB5_CTX_FLAG_CFX               0x00000002
-+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY   0x00000004
+ static int parse_sec(char *sec, int *pseudoflavour)
+@@ -104,13 +85,13 @@ static int parse_sec(char *sec, int *pse
+                                 "exceeded\n"));
+                       return 0;
+               }
+-              for (i = 0; i < FMAPSIZE; i++) {
++              for (i = 0; i < flav_map_size; i++) {
+                       if (strcmp(sec, flav_map[i].flavour) == 0) {
+                               pseudoflavour[num_flavour++] = flav_map[i].fnum;
+                               break;
+                       }
+               }
+-              if (i == FMAPSIZE) {
++              if (i == flav_map_size) {
+                       fprintf(stderr,
+                               _("mount: unknown security type %s\n"), sec);
+                       return 0;
+@@ -399,7 +380,7 @@ int nfs4mount(const char *spec, const ch
+               printf("sec = ");
+               for (pf_cnt = 0; pf_cnt < num_flavour; pf_cnt++) {
+-                      for (i = 0; i < FMAPSIZE; i++) {
++                      for (i = 0; i < flav_map_size; i++) {
+                               if (flav_map[i].fnum == pseudoflavour[pf_cnt]) {
+                                       printf("%s", flav_map[i].flavour);
+                                       break;
+diff -puN utils/mount/nfs4_mount.h~CITI_NFS4_ALL utils/mount/nfs4_mount.h
+--- nfs-utils-1.1.0/utils/mount/nfs4_mount.h~CITI_NFS4_ALL     2007-06-22 10:52:21.626744000 -0400
++++ nfs-utils-1.1.0-kwc/utils/mount/nfs4_mount.h       2007-06-22 10:52:24.715391000 -0400
+@@ -67,18 +67,6 @@ struct nfs4_mount_data {
+ #define NFS4_MOUNT_STRICTLOCK 0x1000  /* 1 */
+ #define NFS4_MOUNT_FLAGMASK   0xFFFF
+-/* pseudoflavors: */
+-
+-#define RPC_AUTH_GSS_KRB5       390003
+-#define RPC_AUTH_GSS_KRB5I      390004
+-#define RPC_AUTH_GSS_KRB5P      390005
+-#define RPC_AUTH_GSS_LKEY       390006
+-#define RPC_AUTH_GSS_LKEYI      390007
+-#define RPC_AUTH_GSS_LKEYP      390008
+-#define RPC_AUTH_GSS_SPKM       390009
+-#define RPC_AUTH_GSS_SPKMI      390010
+-#define RPC_AUTH_GSS_SPKMP      390011
+-
+ int nfs4mount(const char *, const char *, int *, char **,
+       char **, int);
  
- int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf,
-                                gss_OID mech);
-diff --git a/utils/gssd/context_lucid.c b/utils/gssd/context_lucid.c
-index 3550762..c824dcd 100644
---- a/utils/gssd/context_lucid.c
-+++ b/utils/gssd/context_lucid.c
-@@ -40,6 +40,7 @@ #ifdef HAVE_LUCID_CONTEXT_SUPPORT
- #include <stdio.h>
- #include <syslog.h>
- #include <string.h>
-+#include <errno.h>
- #include "gss_util.h"
- #include "gss_oids.h"
- #include "err_util.h"
-@@ -113,15 +114,13 @@ #ifdef HAVE_HEIMDAL
-        * Note that the rfc1964 version only supports DES enctypes.
-        */
-       if (lctx->rfc1964_kd.ctx_key.type != 4) {
--              printerr(1, "prepare_krb5_rfc1964_buffer: "
--                          "overriding heimdal keytype (%d => %d)\n",
--                          lctx->rfc1964_kd.ctx_key.type, 4);
-+              printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
-+                       __FUNCTION__, lctx->rfc1964_kd.ctx_key.type, 4);
-               lctx->rfc1964_kd.ctx_key.type = 4;
-       }
+diff -puN support/include/nfslib.h~CITI_NFS4_ALL support/include/nfslib.h
+--- nfs-utils-1.1.0/support/include/nfslib.h~CITI_NFS4_ALL     2007-06-22 10:52:31.311234000 -0400
++++ nfs-utils-1.1.0-kwc/support/include/nfslib.h       2007-06-22 10:52:39.718626000 -0400
+@@ -51,6 +51,14 @@
+ #define       _PATH_PROC_EXPORTS_ALT  "/proc/fs/nfsd/exports"
  #endif
--      printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with "
--               "enctype %d and length %d\n",
--               lctx->rfc1964_kd.ctx_key.type,
-+      printerr(2, "%s: serializing keys with enctype %d and length %d\n",
-+               __FUNCTION__, lctx->rfc1964_kd.ctx_key.type,
-                lctx->rfc1964_kd.ctx_key.length);
-       /* derive the encryption key and copy it into buffer */
-@@ -152,15 +151,361 @@ out_err:
-       return -1;
- }
  
--static int
--prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx,
--      gss_buffer_desc *buf)
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
++/* Maximum number of security flavors on an export: */
++#define SECFLAVOR_COUNT 8
 +
-+/* for 3DES */
-+#define KG_USAGE_SEAL 22
-+#define KG_USAGE_SIGN 23
-+#define KG_USAGE_SEQ  24
-+
-+/* for rfc???? */
-+#define KG_USAGE_ACCEPTOR_SEAL  22
-+#define KG_USAGE_ACCEPTOR_SIGN  23
-+#define KG_USAGE_INITIATOR_SEAL 24
-+#define KG_USAGE_INITIATOR_SIGN 25
-+
-+/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
-+enum seal_alg {
-+  SEAL_ALG_NONE            = 0xffff,
-+  SEAL_ALG_DES             = 0x0000,
-+  SEAL_ALG_1               = 0x0001, /* not published */
-+  SEAL_ALG_MICROSOFT_RC4   = 0x0010, /* microsoft w2k;  */
-+  SEAL_ALG_DES3KD          = 0x0002
++struct sec_entry {
++      struct flav_info *flav;
++      int flags;
 +};
 +
-+#define KEY_USAGE_SEED_ENCRYPTION     0xAA
-+#define KEY_USAGE_SEED_INTEGRITY      0x55
-+#define KEY_USAGE_SEED_CHECKSUM               0x99
-+#define K5CLENGTH 5
-+
-+/* Flags for version 2 context flags */
-+#define KRB5_CTX_FLAG_INITIATOR               0x00000001
-+#define KRB5_CTX_FLAG_CFX             0x00000002
-+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
-+
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/*
-+ * We don't have "legal" access to these MIT-only
-+ * structures located in libk5crypto
-+ */
-+extern void krb5int_enc_arcfour;
-+extern void krb5int_enc_des3;
-+extern void krb5int_enc_aes128;
-+extern void krb5int_enc_aes256;
-+extern int krb5_derive_key();
-+
-+static void
-+key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout)
- {
--      printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n");
--      return -1;
-+      memset(kout, '\0', sizeof(kout));
-+#ifdef HAVE_KRB5
-+      kout->enctype = lin->type;
-+      kout->length = lin->length;
-+      kout->contents = lin->data;
-+#else
-+      kout->keytype = lin->type;
-+      kout->keyvalue.length = lin->length;
-+      kout->keyvalue.data = lin->data;
-+#endif
-+}
-+
-+static void
-+key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout)
-+{
-+      memset(lout, '\0', sizeof(lout));
-+#ifdef HAVE_KRB5
-+      lout->type = kin->enctype;
-+      lout->length = kin->length;
-+      lout->data = kin->contents;
-+#else
-+      lout->type = kin->keytype;
-+      lout->length = kin->keyvalue.length;
-+      memcpy(lout->data, kin->keyvalue.data, kin->keyvalue.length);
-+#endif
-+}
-+
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/* XXX Hack alert! XXX  Do NOT submit upstream! XXX */
-+/*
-+ * Function to derive a new key from a given key and given constant data.
-+ */
-+static krb5_error_code
-+derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out,
-+               int usage, char extra)
-+{
-+      krb5_error_code code;
-+      unsigned char constant_data[K5CLENGTH];
-+      krb5_data datain;
-+      int keylength;
-+      void *enc;
-+      krb5_keyblock kin, kout;  /* must send krb5_keyblock, not lucid! */
-+#ifdef HAVE_HEIMDAL
-+      krb5_context kcontext;
-+      krb5_keyblock *outkey;
-+#endif
-+
-+      /*
-+       * XXX Hack alert.  We don't have "legal" access to these
-+       * values and structures located in libk5crypto
-+       */
-+      switch (in->type) {
-+      case ENCTYPE_DES3_CBC_SHA1:
-+#ifdef HAVE_KRB5
-+      case ENCTYPE_DES3_CBC_RAW:
-+#endif
-+              keylength = 24;
-+#ifdef HAVE_KRB5
-+              enc = &krb5int_enc_des3;
-+#endif
-+              break;
-+      case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
-+              keylength = 16;
-+#ifdef HAVE_KRB5
-+              enc = &krb5int_enc_aes128;
-+#endif
-+              break;
-+      case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
-+              keylength = 32;
-+#ifdef HAVE_KRB5
-+              enc = &krb5int_enc_aes256;
-+#endif
-+              break;
-+      default:
-+              code = KRB5_BAD_ENCTYPE;
-+              goto out;
-+      }
-+
-+      /* allocate memory for output key */
-+      if ((out->data = malloc(keylength)) == NULL) {
-+              code = ENOMEM;
-+              goto out;
-+      }
-+      out->length = keylength;
-+      out->type = in->type;
-+
-+      /* Convert to correct format for call to krb5_derive_key */
-+      key_lucid_to_krb5(in, &kin);
-+      key_lucid_to_krb5(out, &kout);
-+
-+      datain.data = (char *) constant_data;
-+      datain.length = K5CLENGTH;
-+
-+      ((char *)(datain.data))[0] = (usage>>24)&0xff;
-+      ((char *)(datain.data))[1] = (usage>>16)&0xff;
-+      ((char *)(datain.data))[2] = (usage>>8)&0xff;
-+      ((char *)(datain.data))[3] = usage&0xff;
-+
-+      ((char *)(datain.data))[4] = (char) extra;
-+
-+#ifdef HAVE_KRB5
-+      code = krb5_derive_key(enc, &kin, &kout, &datain);
-+#else
-+      if ((code = krb5_init_context(&kcontext))) {
-+      }
-+      code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey);
-+#endif
-+      if (code) {
-+              free(out->data);
-+              out->data = NULL;
-+              goto out;
-+      }
-+#ifdef HAVE_KRB5
-+      key_krb5_to_lucid(&kout, out);
-+#else
-+      key_krb5_to_lucid(outkey, out);
-+      krb5_free_keyblock(kcontext, outkey);
-+      krb5_free_context(kcontext);
-+#endif
-+
-+  out:
-+      if (code)
-+              printerr(0, "ERROR: %s: returning error %d (%s)\n",
-+                       __FUNCTION__, code, error_message(code));
-+      return (code);
- }
-+/*
-+ * Prepare a new-style buffer, as defined in rfc4121 (a.k.a. cfx),
-+ * to send to the kernel for newer encryption types -- or for DES3.
-+ *
-+ * The new format is:
-+ *
-+ *    u32 initiate;                   ( whether we are the initiator or not )
-+ *    s32 endtime;
-+ *    u32 flags;
-+ *    #define KRB5_CTX_FLAG_INITIATOR         0x00000001
-+ *    #define KRB5_CTX_FLAG_CFX               0x00000002
-+ *    #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY   0x00000004
-+ *    u64 seq_send;
-+ *    u32  enctype;                   ( encrption type of keys )
-+ *    u32  size_of_each_key;          ( size of each key in bytes )
-+ *    u32  number_of_keys;            ( N -- should always be 3 for now )
-+ *    keydata-1;                      ( Ke )
-+ *    keydata-2;                      ( Ki )
-+ *    keydata-3;                      ( Kc )
-+ *
-+ */
-+static int
-+prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx,
-+                          gss_buffer_desc *buf)
-+{
-+      char *p, *end;
-+      uint32_t v2_flags = 0;
-+      gss_krb5_lucid_key_t enc_key;
-+      gss_krb5_lucid_key_t derived_key;
-+      gss_buffer_desc fakeoid;
-+      uint32_t enctype;
-+      uint32_t keysize;
-+      uint32_t numkeys;
-+
-+      memset(&enc_key, 0, sizeof(enc_key));
-+      memset(&fakeoid, 0, sizeof(fakeoid));
-+
-+      if (!(buf->value = calloc(1, MAX_CTX_LEN)))
-+              goto out_err;
-+      p = buf->value;
-+      end = buf->value + MAX_CTX_LEN;
-+
-+      /* Version 2 */
-+      if (WRITE_BYTES(&p, end, lctx->initiate)) goto out_err;
-+      if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
-+
-+      if (lctx->initiate)
-+              v2_flags |= KRB5_CTX_FLAG_INITIATOR;
-+      if (lctx->protocol != 0)
-+              v2_flags |= KRB5_CTX_FLAG_CFX;
-+      if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1)
-+              v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
-+
-+      if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
-+
-+      if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err;
-+
-+      /* Protocol 0 here implies DES3 or RC4 */
-+      printerr(2, "%s: protocol %d\n", __FUNCTION__, lctx->protocol);
-+      if (lctx->protocol == 0) {
-+              enctype = lctx->rfc1964_kd.ctx_key.type;
-+#ifdef HAVE_HEIMDAL
-+              /*
-+               * The kernel gss code expects ENCTYPE_DES3_CBC_RAW (6) for
-+               * 3des keys, but Heimdal key has ENCTYPE_DES3_CBC_SHA1 (16).
-+               * Force the Heimdal enctype to 6.
-+               */
-+              if (enctype == ENCTYPE_DES3_CBC_SHA1) {
-+                      printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
-+                               __FUNCTION__, enctype, 6);
-+
-+                      enctype = 6;
-+              }
-+#endif
-+              keysize = lctx->rfc1964_kd.ctx_key.length;
-+              numkeys = 3;    /* XXX is always gonna be three? */
-+      } else {
-+              if (lctx->cfx_kd.have_acceptor_subkey) {
-+                      enctype = lctx->cfx_kd.acceptor_subkey.type;
-+                      keysize = lctx->cfx_kd.acceptor_subkey.length;
-+              } else {
-+                      enctype = lctx->cfx_kd.ctx_key.type;
-+                      keysize = lctx->cfx_kd.ctx_key.length;
-+              }
-+              numkeys = 3;
-+      }
-+      printerr(2, "%s: serializing %d keys with enctype %d and size %d\n",
-+               __FUNCTION__, numkeys, enctype, keysize);
-+      if (WRITE_BYTES(&p, end, enctype)) goto out_err;
-+      if (WRITE_BYTES(&p, end, keysize)) goto out_err;
-+      if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
-+
-+      if (lctx->protocol == 0) {
-+              /* derive and send down: Ke, Ki, and Kc */
-+              /* Ke */
-+              if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
-+                              lctx->rfc1964_kd.ctx_key.length))
-+                      goto out_err;
-+
-+              /* Ki */
-+              if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
-+                              lctx->rfc1964_kd.ctx_key.length))
-+                      goto out_err;
-+
-+              /* Kc */
-+              if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key,
-+                              &derived_key,
-+                              KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
-+                      goto out_err;
-+              if (write_bytes(&p, end, derived_key.data,
-+                              derived_key.length))
-+                      goto out_err;
-+              free(derived_key.data);
-+      } else {
-+              gss_krb5_lucid_key_t *keyptr;
-+              uint32_t sign_usage, seal_usage;
-+
-+              if (lctx->cfx_kd.have_acceptor_subkey)
-+                      keyptr = &lctx->cfx_kd.acceptor_subkey;
-+              else
-+                      keyptr = &lctx->cfx_kd.ctx_key;
-+
-+              if (lctx->initiate == 1) {
-+                      sign_usage = KG_USAGE_INITIATOR_SIGN;
-+                      seal_usage = KG_USAGE_INITIATOR_SEAL;
-+              } else {
-+                      sign_usage = KG_USAGE_ACCEPTOR_SIGN;
-+                      seal_usage = KG_USAGE_ACCEPTOR_SEAL;
-+              }
-+
-+              /* derive and send down: Ke, Ki, and Kc */
-+
-+              /* Ke */
-+              if (derive_key_lucid(keyptr, &derived_key,
-+                             seal_usage, KEY_USAGE_SEED_ENCRYPTION))
-+                      goto out_err;
-+              if (write_bytes(&p, end, derived_key.data,
-+                              derived_key.length))
-+                      goto out_err;
-+              free(derived_key.data);
-+
-+              /* Ki */
-+              if (derive_key_lucid(keyptr, &derived_key,
-+                             seal_usage, KEY_USAGE_SEED_INTEGRITY))
-+                      goto out_err;
-+              if (write_bytes(&p, end, derived_key.data,
-+                              derived_key.length))
-+                      goto out_err;
-+              free(derived_key.data);
-+
-+              /* Kc */
-+              if (derive_key_lucid(keyptr, &derived_key,
-+                             sign_usage, KEY_USAGE_SEED_CHECKSUM))
-+                      goto out_err;
-+              if (write_bytes(&p, end, derived_key.data,
-+                              derived_key.length))
-+                      goto out_err;
-+              free(derived_key.data);
-+      }
-+
-+      buf->length = p - (char *)buf->value;
-+      return 0;
-+
-+out_err:
-+      printerr(0, "ERROR: %s: failed serializing krb5 context for kernel\n",
-+               __FUNCTION__);
-+      if (buf->value) {
-+              free(buf->value);
-+              buf->value = NULL;
-+      }
-+      buf->length = 0;
-+      if (enc_key.data) {
-+              free(enc_key.data);
-+              enc_key.data = NULL;
-+      }
-+      return -1;
-+}
- int
- serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf)
- {
-@@ -170,7 +515,7 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
-       gss_krb5_lucid_context_v1_t *lctx = 0;
-       int retcode = 0;
--      printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n");
-+      printerr(2, "DEBUG: %s: lucid version!\n", __FUNCTION__);
-       maj_stat = gss_export_lucid_sec_context(&min_stat, &ctx,
-                                               1, &return_ctx);
-       if (maj_stat != GSS_S_COMPLETE) {
-@@ -192,11 +537,20 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
-               break;
-       }
--      /* Now lctx points to a lucid context that we can send down to kernel */
--      if (lctx->protocol == 0)
-+        /*
-+       * Now lctx points to a lucid context that we can send down to kernel
-+       *
-+       * Note: we send down different information to the kernel depending
-+       * on the protocol version and the enctyption type.
-+       * For protocol version 0 with all enctypes besides DES3, we use
-+       * the original format.  For protocol version != 0 or DES3, we
-+       * send down the new style information.
-+       */
-+
-+      if (lctx->protocol == 0 && lctx->rfc1964_kd.ctx_key.type <= 4)
-               retcode = prepare_krb5_rfc1964_buffer(lctx, buf);
-       else
--              retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf);
-+              retcode = prepare_krb5_rfc4121_buffer(lctx, buf);
-       maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx);
-       if (maj_stat != GSS_S_COMPLETE) {
-@@ -206,8 +560,8 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
-       }
-       if (retcode) {
--              printerr(1, "serialize_krb5_ctx: prepare_krb5_*_buffer "
--                       "failed (retcode = %d)\n", retcode);
-+              printerr(1, "%s: prepare_krb5_*_buffer failed (retcode = %d)\n",
-+                       __FUNCTION__, retcode);
-               goto out_err;
-       }
-@@ -217,4 +571,7 @@ out_err:
-       printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
-       return -1;
- }
-+
-+
-+
- #endif /* HAVE_LUCID_CONTEXT_SUPPORT */
-diff --git a/utils/gssd/context_mit.c b/utils/gssd/context_mit.c
-index 94b2266..cd6ab0f 100644
---- a/utils/gssd/context_mit.c
-+++ b/utils/gssd/context_mit.c
-@@ -1,5 +1,5 @@
  /*
--  Copyright (c) 2004 The Regents of the University of Michigan.
-+  Copyright (c) 2004-2006 The Regents of the University of Michigan.
-   All rights reserved.
-   Redistribution and use in source and binary forms, with or without
-@@ -36,6 +36,7 @@ #ifdef HAVE_KRB5
- #include <stdio.h>
- #include <syslog.h>
- #include <string.h>
-+#include <errno.h>
- #include <gssapi/gssapi.h>
- #include <rpc/rpc.h>
- #include <rpc/auth_gss.h>
-@@ -50,8 +51,7 @@ #if (KRB5_VERSION > 131)
- /* XXX argggg, there's gotta be a better way than just duplicating this
-  * whole struct.  Unfortunately, this is in a "private" header file,
-  * so this is our best choice at this point :-/
-- *
-- * XXX Does this match the Heimdal definition?  */
-+ */
+  * Data related to a single exports entry as returned by getexportent.
+  * FIXME: export options should probably be parsed at a later time to
+@@ -76,6 +84,7 @@ struct exportent {
+       int             e_fslocmethod;
+       char *          e_fslocdata;
+       char *          e_uuid;
++      struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
+ };
  
- typedef struct _krb5_gss_ctx_id_rec {
-    unsigned int initiate : 1;   /* nonzero if initiating, zero if accepting */
-@@ -139,6 +139,124 @@ write_keyblock(char **p, char *end, stru
+ struct rmtabent {
+@@ -89,6 +98,7 @@ struct rmtabent {
+  */
+ void                  setexportent(char *fname, char *type);
+ struct exportent *    getexportent(int,int);
++void                  secinfo_show(FILE *fp, struct exportent *ep);
+ void                  putexportent(struct exportent *xep);
+ void                  endexportent(void);
+ struct exportent *    mkexportent(char *hname, char *path, char *opts);
+diff -puN utils/exportfs/exportfs.c~CITI_NFS4_ALL utils/exportfs/exportfs.c
+--- nfs-utils-1.1.0/utils/exportfs/exportfs.c~CITI_NFS4_ALL    2007-06-22 10:52:33.386332000 -0400
++++ nfs-utils-1.1.0-kwc/utils/exportfs/exportfs.c      2007-06-22 10:52:40.698175000 -0400
+@@ -515,6 +515,7 @@ dump(int verbose)
+                               break;
+ #endif
+                       }
++                      secinfo_show(stdout, ep);
+                       printf("%c\n", (c != '(')? ')' : ' ');
+               }
+       }
+diff -puN utils/mountd/cache.c~CITI_NFS4_ALL utils/mountd/cache.c
+--- nfs-utils-1.1.0/utils/mountd/cache.c~CITI_NFS4_ALL 2007-06-22 10:52:38.862018000 -0400
++++ nfs-utils-1.1.0-kwc/utils/mountd/cache.c   2007-06-22 10:52:40.837142000 -0400
+@@ -30,6 +30,7 @@
+ #include "mountd.h"
+ #include "xmalloc.h"
+ #include "fsloc.h"
++#include "pseudoflavors.h"
+ #ifdef USE_BLKID
+ #include "blkid/blkid.h"
+@@ -518,6 +519,25 @@ static void write_fsloc(FILE *f, struct 
+       release_replicas(servers);
  }
  
- /*
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ *
-+ * We shouldn't be using these definitions
-+ *
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ */
-+/* for 3DES */
-+#define KG_USAGE_SEAL 22
-+#define KG_USAGE_SIGN 23
-+#define KG_USAGE_SEQ  24
-+
-+/* for rfc???? */
-+#define KG_USAGE_ACCEPTOR_SEAL  22
-+#define KG_USAGE_ACCEPTOR_SIGN  23
-+#define KG_USAGE_INITIATOR_SEAL 24
-+#define KG_USAGE_INITIATOR_SIGN 25
-+
-+/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
-+enum seal_alg {
-+  SEAL_ALG_NONE            = 0xffff,
-+  SEAL_ALG_DES             = 0x0000,
-+  SEAL_ALG_1               = 0x0001, /* not published */
-+  SEAL_ALG_MICROSOFT_RC4   = 0x0010, /* microsoft w2k;  */
-+  SEAL_ALG_DES3KD          = 0x0002
-+};
-+
-+#define KEY_USAGE_SEED_ENCRYPTION     0xAA
-+#define KEY_USAGE_SEED_INTEGRITY      0x55
-+#define KEY_USAGE_SEED_CHECKSUM               0x99
-+#define K5CLENGTH 5
-+
-+extern void krb5_enc_des3;
-+extern void krb5int_enc_des3;
-+extern void krb5int_enc_arcfour;
-+extern void krb5int_enc_aes128;
-+extern void krb5int_enc_aes256;
-+extern int krb5_derive_key();
-+
-+/*
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ *
-+ * We should be passing down a single key to the kernel
-+ * and it should be deriving the other keys.  We cannot
-+ * depend on any of this stuff being accessible in the
-+ * future.
-+ *
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ * XXX Hack alert! XXX Do NOT submit upstream!
-+ */
-+/*
-+ * Function to derive a new key from a given key and given constant data.
-+ */
-+static krb5_error_code
-+derive_key(const krb5_keyblock *in, krb5_keyblock *out, int usage, char extra)
++static void write_secinfo(FILE *f, struct exportent *ep)
 +{
-+      krb5_error_code code;
-+      unsigned char constant_data[K5CLENGTH];
-+      krb5_data datain;
-+      int keylength;
-+      void *enc;
-+
-+      switch (in->enctype) {
-+#ifdef ENCTYPE_DES3_CBC_RAW
-+      case ENCTYPE_DES3_CBC_RAW:
-+              keylength = 24;
-+/* Extra hack, the structure was renamed as rc4 was added... */
-+#if defined(ENCTYPE_ARCFOUR_HMAC)
-+              enc = &krb5int_enc_des3;
-+#else
-+              enc = &krb5_enc_des3;
-+#endif
-+              break;
-+#endif
-+#ifdef ENCTYPE_ARCFOUR_HMAC
-+      case ENCTYPE_ARCFOUR_HMAC:
-+              keylength = 16;
-+              enc = &krb5int_enc_arcfour;
-+              break;
-+#endif
-+      default:
-+              code = KRB5_BAD_ENCTYPE;
-+              goto out;
-+      }
++      struct sec_entry *p;
 +
-+      /* allocate memory for output key */
-+      if ((out->contents = malloc(keylength)) == NULL) {
-+              code = ENOMEM;
-+              goto out;
++      for (p = ep->e_secinfo; p->flav; p++)
++              ; /* Do nothing */
++      if (p == ep->e_secinfo) {
++              /* There was no sec= option */
++              return;
 +      }
-+      out->length = keylength;
-+      out->enctype = in->enctype;
-+
-+      datain.data = (char *) constant_data;
-+      datain.length = K5CLENGTH;
-+
-+      datain.data[0] = (usage>>24)&0xff;
-+      datain.data[1] = (usage>>16)&0xff;
-+      datain.data[2] = (usage>>8)&0xff;
-+      datain.data[3] = usage&0xff;
-+
-+      datain.data[4] = (char) extra;
-+
-+      if ((code = krb5_derive_key(enc, in, out, &datain))) {
-+              free(out->contents);
-+              out->contents = NULL;
++      qword_print(f, "secinfo");
++      qword_printint(f, p - ep->e_secinfo);
++      for (p = ep->e_secinfo; p->flav; p++) {
++              qword_printint(f, p->flav->fnum);
++              qword_printint(f, p->flags);
 +      }
 +
-+  out:
-+      if (code)
-+              printerr(0, "ERROR: derive_key returning error %d (%s)\n",
-+                       code, error_message(code));
-+      return (code);
 +}
 +
-+/*
-  * We really shouldn't know about glue-layer context structure, but
-  * we need to get at the real krb5 context pointer.  This should be
-  * removed as soon as we say there is no support for MIT Kerberos
-@@ -154,48 +272,124 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
+ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp)
  {
-       krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id;
-       char *p, *end;
--      static int constant_one = 1;
-       static int constant_zero = 0;
-+      static int constant_one = 1;
-+      static int constant_two = 2;
-       uint32_t word_seq_send;
-+      u_int64_t seq_send_64bit;
-+      uint32_t v2_flags = 0;
-+      krb5_keyblock derived_key;
-+      uint32_t numkeys;
-       if (!(buf->value = calloc(1, MAX_CTX_LEN)))
-               goto out_err;
-       p = buf->value;
-       end = buf->value + MAX_CTX_LEN;
--      if (kctx->initiate) {
--              if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
--      }
--      else {
--              if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
--      }
--      if (kctx->seed_init) {
--              if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
--      }
--      else {
--              if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
--      }
--      if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
--              goto out_err;
--      if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
--      if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
--      if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
--      word_seq_send = kctx->seq_send;
--      if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
--      if (write_oid(&p, end, kctx->mech_used)) goto out_err;
-+      switch (kctx->sealalg) {
-+      case SEAL_ALG_DES:
-+              /* Old format of context to the kernel */
-+              if (kctx->initiate) {
-+                      if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
-+              }
-+              else {
-+                      if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
-+              }
-+              if (kctx->seed_init) {
-+                      if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
-+              }
-+              else {
-+                      if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
-+              }
-+              if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
-+                      goto out_err;
-+              if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
-+              if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
-+              if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
-+              word_seq_send = kctx->seq_send;
-+              if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
-+              if (write_oid(&p, end, kctx->mech_used)) goto out_err;
-+
-+              printerr(2, "serialize_krb5_ctx: serializing keys with "
-+                       "enctype %d and length %d\n",
-+                       kctx->enc->enctype, kctx->enc->length);
-+
-+              if (write_keyblock(&p, end, kctx->enc)) goto out_err;
-+              if (write_keyblock(&p, end, kctx->seq)) goto out_err;
-+              break;
-+      case SEAL_ALG_MICROSOFT_RC4:
-+      case SEAL_ALG_DES3KD:
-+              /* New format of context to the kernel */
-+              /* s32 endtime;
-+               * u32 flags;
-+               * #define KRB5_CTX_FLAG_INITIATOR        0x00000001
-+               * #define KRB5_CTX_FLAG_CFX              0x00000002
-+               * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY  0x00000004
-+               * u64 seq_send;
-+               * u32  enctype;
-+               * u32  size_of_each_key;    (  size in bytes )
-+               * u32  number_of_keys;      (  N (assumed to be 3 for now) )
-+               * keydata-1;                (  Ke  (Kenc for DES3) )
-+               * keydata-2;                (  Ki  (Kseq for DES3) )
-+               * keydata-3;                (  Kc (derived checksum key) )
-+               */
-+              if (kctx->initiate) {
-+                      if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
-+              }
-+              else {
-+                      if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
-+              }
-+              if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
-+
-+              /* Only applicable flag for this is initiator */
-+              if (kctx->initiate) v2_flags |= KRB5_CTX_FLAG_INITIATOR;
-+              if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
-+
-+              seq_send_64bit = kctx->seq_send;
-+              if (WRITE_BYTES(&p, end, seq_send_64bit)) goto out_err;
--      printerr(2, "serialize_krb5_ctx: serializing keys with "
--               "enctype %d and length %d\n",
--               kctx->enc->enctype, kctx->enc->length);
-+              if (WRITE_BYTES(&p, end, kctx->enc->enctype)) goto out_err;
-+              if (WRITE_BYTES(&p, end, kctx->enc->length)) goto out_err;
-+              numkeys = 3;
-+              if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
-+              printerr(2, "serialize_krb5_ctx: serializing %d keys with "
-+                       "enctype %d and size %d\n",
-+                       numkeys, kctx->enc->enctype, kctx->enc->length);
--      if (write_keyblock(&p, end, kctx->enc)) goto out_err;
--      if (write_keyblock(&p, end, kctx->seq)) goto out_err;
-+              /* Ke */
-+              if (write_bytes(&p, end, kctx->enc->contents,
-+                              kctx->enc->length))
-+                      goto out_err;
-+
-+              /* Ki */
-+              if (write_bytes(&p, end, kctx->enc->contents,
-+                              kctx->enc->length))
-+                      goto out_err;
-+
-+              /* Kc */
-+              if (derive_key(kctx->seq, &derived_key,
-+                             KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
-+                      goto out_err;
-+              if (write_bytes(&p, end, derived_key.contents,
-+                              derived_key.length))
-+                      goto out_err;
-+              free(derived_key.contents);
-+              break;
-+      default:
-+              printerr(0, "ERROR: serialize_krb5_ctx: unsupported seal "
-+                       "algorithm %d\n", kctx->sealalg);
-+              goto out_err;
-+      }
-       buf->length = p - (char *)buf->value;
-       return 0;
-+
- out_err:
-       printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
--      if (buf->value) free(buf->value);
-+      if (buf->value) {
-+              free(buf->value);
-+      }
-+      buf->value = NULL;
-       buf->length = 0;
-       return -1;
- }
+       qword_print(f, domain);
+@@ -529,6 +549,7 @@ static int dump_to_cache(FILE *f, char *
+               qword_printint(f, exp->e_anongid);
+               qword_printint(f, exp->e_fsid);
+               write_fsloc(f, exp, path);
++              write_secinfo(f, exp);
+ #if USE_BLKID
+               if (exp->e_uuid == NULL) {
+                       char u[16];
+
+_
This page took 0.09339 seconds and 4 git commands to generate.