From 14bcaf3a6223c211ea378ed0fcff1252f2f19ede Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Tue, 14 Aug 2007 14:12:41 +0000 Subject: [PATCH] - updated to latest patchset Changed files: nfs-utils-CITI_NFS4.patch -> 1.5 --- nfs-utils-CITI_NFS4.patch | 1773 ++++++++++--------------------------- 1 file changed, 454 insertions(+), 1319 deletions(-) diff --git a/nfs-utils-CITI_NFS4.patch b/nfs-utils-CITI_NFS4.patch index 3e2ec9f..66ea292 100644 --- a/nfs-utils-CITI_NFS4.patch +++ b/nfs-utils-CITI_NFS4.patch @@ -1,134 +1,217 @@ -Add secinfo processing. -From: Fred Isaman -Signed-off-by: Fred Isaman +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 + * Update to nfs-utils-1.1.0 -Signed-off-by: Kevin Coffman + * 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 + * 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 -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 ⅇ } - 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; iflavour, 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<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<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 - #include -+#include - #include - #include - #include -@@ -105,6 +106,7 @@ #include - #include - #include - #include -+#include - #include - #include - #include -@@ -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 - /* 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 - #include - #include -+#include - #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 - #include - #include -+#include - #include - #include - #include -@@ -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]; + +_ -- 2.44.0