3 The complete set of CITI nfs-utils patches rolled into one patch.
5 Changes since 1.0.10-CITI_NFS4_ALL-4:
7 * Update to nfs-utils-1.0.11
9 * Include missing fslocations files and a small change so that
12 * Include several mount patches from Steve Dickson
14 * Add a patch to put the mount.nfs[4] and umount.nfs[4] in the
15 place where mount expects them during install.
20 nfs-utils-1.0.11-kwc/Makefile.in | 136
21 nfs-utils-1.0.11-kwc/aclocal.m4 | 250
22 nfs-utils-1.0.11-kwc/configure | 4436 +++++++++++-----
23 nfs-utils-1.0.11-kwc/linux-nfs/Makefile.in | 88
24 nfs-utils-1.0.11-kwc/support/Makefile.in | 120
25 nfs-utils-1.0.11-kwc/support/export/Makefile.in | 113
26 nfs-utils-1.0.11-kwc/support/export/export.c | 2
27 nfs-utils-1.0.11-kwc/support/include/Makefile.in | 124
28 nfs-utils-1.0.11-kwc/support/include/fstab.h | 8
29 nfs-utils-1.0.11-kwc/support/include/nfs/Makefile.in | 88
30 nfs-utils-1.0.11-kwc/support/include/nfs_mntent.h | 8
31 nfs-utils-1.0.11-kwc/support/include/nfslib.h | 6
32 nfs-utils-1.0.11-kwc/support/include/rpcsvc/Makefile.in | 88
33 nfs-utils-1.0.11-kwc/support/include/sys/Makefile.in | 120
34 nfs-utils-1.0.11-kwc/support/include/sys/fs/Makefile.in | 88
35 nfs-utils-1.0.11-kwc/support/misc/Makefile.in | 113
36 nfs-utils-1.0.11-kwc/support/nfs/Makefile.in | 113
37 nfs-utils-1.0.11-kwc/support/nfs/conn.c | 2
38 nfs-utils-1.0.11-kwc/support/nfs/exports.c | 149
39 nfs-utils-1.0.11-kwc/support/nfs/fstab.c | 57
40 nfs-utils-1.0.11-kwc/tools/Makefile.in | 120
41 nfs-utils-1.0.11-kwc/tools/getiversion/Makefile.in | 126
42 nfs-utils-1.0.11-kwc/tools/locktest/Makefile.in | 126
43 nfs-utils-1.0.11-kwc/tools/nlmtest/Makefile.in | 88
44 nfs-utils-1.0.11-kwc/tools/rpcdebug/Makefile.in | 135
45 nfs-utils-1.0.11-kwc/tools/rpcgen/Makefile.in | 198
46 nfs-utils-1.0.11-kwc/utils/Makefile.in | 120
47 nfs-utils-1.0.11-kwc/utils/exportfs/Makefile.in | 130
48 nfs-utils-1.0.11-kwc/utils/exportfs/exportfs.c | 5
49 nfs-utils-1.0.11-kwc/utils/exportfs/exports.man | 14
50 nfs-utils-1.0.11-kwc/utils/gssd/Makefile.in | 356 -
51 nfs-utils-1.0.11-kwc/utils/gssd/context.h | 6
52 nfs-utils-1.0.11-kwc/utils/gssd/context_lucid.c | 391 +
53 nfs-utils-1.0.11-kwc/utils/gssd/context_mit.c | 256
54 nfs-utils-1.0.11-kwc/utils/gssd/gssd.c | 17
55 nfs-utils-1.0.11-kwc/utils/gssd/gssd.h | 3
56 nfs-utils-1.0.11-kwc/utils/gssd/gssd_main_loop.c | 4
57 nfs-utils-1.0.11-kwc/utils/gssd/gssd_proc.c | 22
58 nfs-utils-1.0.11-kwc/utils/gssd/krb5_util.c | 228
59 nfs-utils-1.0.11-kwc/utils/gssd/krb5_util.h | 2
60 nfs-utils-1.0.11-kwc/utils/idmapd/Makefile.in | 124
61 nfs-utils-1.0.11-kwc/utils/lockd/Makefile.in | 126
62 nfs-utils-1.0.11-kwc/utils/mount/Makefile.am | 15
63 nfs-utils-1.0.11-kwc/utils/mount/Makefile.in | 140
64 nfs-utils-1.0.11-kwc/utils/mount/mount.c | 211
65 nfs-utils-1.0.11-kwc/utils/mount/nfs4mount.c | 3
66 nfs-utils-1.0.11-kwc/utils/mount/nfs_mount.h | 4
67 nfs-utils-1.0.11-kwc/utils/mount/nfsmount.c | 70
68 nfs-utils-1.0.11-kwc/utils/mount/nfsumount.c | 53
69 nfs-utils-1.0.11-kwc/utils/mountd/Makefile.in | 182
70 nfs-utils-1.0.11-kwc/utils/mountd/cache.c | 16
71 nfs-utils-1.0.11-kwc/utils/mountd/fsloc.c | 188
72 nfs-utils-1.0.11-kwc/utils/mountd/fsloc.h | 50
73 nfs-utils-1.0.11-kwc/utils/nfsd/Makefile.in | 126
74 nfs-utils-1.0.11-kwc/utils/nfsstat/Makefile.in | 124
75 nfs-utils-1.0.11-kwc/utils/rquotad/Makefile.in | 166
76 nfs-utils-1.0.11-kwc/utils/showmount/Makefile.in | 132
77 nfs-utils-1.0.11-kwc/utils/statd/Makefile.in | 126
78 58 files changed, 6974 insertions(+), 3338 deletions(-)
80 --- nfs-utils-1.0.12/utils/mountd/cache.c.orig 2007-02-27 05:55:40.000000000 +0100
81 +++ nfs-utils-1.0.12/utils/mountd/cache.c 2007-03-11 00:38:34.746218136 +0100
83 release_replicas(servers);
86 +static void write_secinfo(FILE *f, struct exportent *ep)
89 + qword_print(f, "secinfo");
90 + for (p=ep->e_secinfo_order; *p>=0; p++)
92 + qword_printint(f, p - ep->e_secinfo_order);
93 + for (p=ep->e_secinfo_order; *p>=0; p++) {
94 + qword_print(f, secflavor_name[*p]);
95 + qword_printint(f, ep->e_secinfo_flags[*p]);
99 static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp)
101 qword_print(f, domain);
103 qword_print(f, "uuid");
104 qword_printhex(f, exp->e_uuid, 16);
106 + write_secinfo(f, exp);
110 --- nfs-utils-1.0.12/support/nfs/exports.c.orig 2007-02-27 05:55:40.000000000 +0100
111 +++ nfs-utils-1.0.12/support/nfs/exports.c 2007-03-11 00:39:09.496198423 +0100
113 static int parsemaptype(char *type);
114 static void freesquash(void);
115 static void syntaxerr(char *msg);
116 +static unsigned int parse_flavors(char *str, struct exportent *ep);
117 +static int secinfo_default(struct exportent *ep);
118 +static void setflags(int mask, unsigned int *ap, struct exportent *ep);
119 +static void clearflags(int mask, unsigned int *ap, struct exportent *ep);
122 setexportent(char *fname, char *type)
124 def_ee.e_mountpoint = NULL;
125 def_ee.e_fslocmethod = FSLOC_NONE;
126 def_ee.e_fslocdata = NULL;
127 + def_ee.e_secinfo_order[0] = -1;
128 def_ee.e_nsquids = 0;
129 def_ee.e_nsqgids = 0;
135 +secinfo_show(FILE *fp, struct exportent *ep)
138 + for (p1=ep->e_secinfo_order; *p1>=0; p1=p2) {
139 + fprintf(fp, ",sec=%s", secflavor_name[*p1]);
140 + for (p2=p1+1; (*p2>=0) && (ep->e_secinfo_flags[*p1]==ep->e_secinfo_flags[*p2]); p2++) {
141 + fprintf(fp, ":%s", secflavor_name[*p2]);
143 + fprintf(fp, ",%s", (ep->e_secinfo_flags[*p1] & NFSEXP_READONLY)? "ro" : "rw");
148 putexportent(struct exportent *ep)
152 fprintf(fp, "%c", esc[i]);
154 fprintf(fp, "\t%s(", ep->e_hostname);
155 - fprintf(fp, "%s,", (ep->e_flags & NFSEXP_READONLY)? "ro" : "rw");
156 fprintf(fp, "%ssync,", (ep->e_flags & NFSEXP_ASYNC)? "a" : "");
157 fprintf(fp, "%swdelay,", (ep->e_flags & NFSEXP_GATHERED_WRITES)?
161 fprintf(fp, "%d,", id[i]);
163 - fprintf(fp, "anonuid=%d,anongid=%d)\n", ep->e_anonuid, ep->e_anongid);
164 + fprintf(fp, "anonuid=%d,anongid=%d", ep->e_anonuid, ep->e_anongid);
165 + secinfo_show(fp, ep);
166 + fprintf(fp, ")\n");
171 ee.e_mountpoint = NULL;
172 ee.e_fslocmethod = FSLOC_NONE;
173 ee.e_fslocdata = NULL;
174 + ee.e_secinfo_order[0] = -1;
179 int had_subtree_opt = 0;
180 char *flname = efname?efname:"command line";
181 int flline = efp?efp->x_line:0;
183 + unsigned int active = 0;
184 + int secmask = NFSEXP_READONLY; /* options that can vary per flavor */
186 squids = ep->e_squids; nsquids = ep->e_nsquids;
187 sqgids = ep->e_sqgids; nsqgids = ep->e_nsqgids;
190 /* process keyword */
191 if (strcmp(opt, "ro") == 0)
192 - ep->e_flags |= NFSEXP_READONLY;
193 + setflags(NFSEXP_READONLY, &active, ep);
194 else if (strcmp(opt, "rw") == 0)
195 - ep->e_flags &= ~NFSEXP_READONLY;
196 + clearflags(NFSEXP_READONLY, &active, ep);
197 else if (!strcmp(opt, "secure"))
198 ep->e_flags &= ~NFSEXP_INSECURE_PORT;
199 else if (!strcmp(opt, "insecure"))
201 } else if (strncmp(opt, "replicas=", 9) == 0) {
202 ep->e_fslocmethod = FSLOC_REPLICA;
203 ep->e_fslocdata = strdup(opt+9);
204 + } else if (strncmp(opt, "sec=", 4) == 0) {
205 + active = parse_flavors(opt+4, ep);
209 xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
210 flname, flline, opt);
216 + active = secinfo_default(ep);
217 + for (p=ep->e_secinfo_order; *p>=0; p++)
218 + ep->e_secinfo_flags[*p] |= (ep->e_flags & ~secmask);
219 + /* If did not use sec= option, ensure e_flags is backward compatible */
220 + ep->e_flags = ep->e_secinfo_flags[ep->e_secinfo_order[0]];
221 ep->e_squids = squids;
222 ep->e_sqgids = sqgids;
223 ep->e_nsquids = nsquids;
224 @@ -663,3 +696,107 @@
225 efname, efp?efp->x_line:0, msg);
228 +char *secflavor_name[SECFLAVOR_COUNT] = { "sys",
238 +secinfo_addflavor(int bit, struct exportent *ep)
241 + for (p=ep->e_secinfo_order; *p>=0; p++) {
247 + ep->e_secinfo_flags[bit] = 0;
251 +secinfo_nameindex(char *name)
254 + for (i=0; i<SECFLAVOR_COUNT; i++) {
255 + if (strcmp(secflavor_name[i], name) == 0)
261 +/* @str is a colon seperated list of security flavors. Their order
262 + * is recorded in @ep, and a bitmap corresponding to the list is returned.
263 + * A zero return indicates an error.
266 +parse_flavors(char *str, struct exportent *ep)
268 + unsigned int out=0;
272 + while ( (flavor=strsep(&str, ":")) ) {
273 + bit = secinfo_nameindex(flavor);
275 + xlog(L_ERROR, "unknown flavor %s\n", flavor);
279 + secinfo_addflavor(bit, ep);
284 +/* Determine a default security flavor based on ep->e_hostname. */
286 +secinfo_default(struct exportent *ep)
289 + if (strncmp(ep->e_hostname, "gss/", 4) == 0) {
290 + i = secinfo_nameindex(ep->e_hostname + 4);
292 + xlog(L_WARNING, "unknown flavor %s\n", ep->e_hostname);
294 + /* Default to auth_sys */
296 + i = secinfo_nameindex("sys");
297 + secinfo_addflavor(i, ep);
301 +/* Sets the bits in @mask for the appropriate security flavor flags. */
303 +setflags(int mask, unsigned int *ap, struct exportent *ep)
305 + int active, flavor=0;
307 + *ap = secinfo_default(ep);
311 + ep->e_secinfo_flags[flavor] |= mask;
317 +/* Clears the bits in @mask for the appropriate security flavor flags. */
319 +clearflags(int mask, unsigned int *ap, struct exportent *ep)
321 + int active, flavor=0;
323 + *ap = secinfo_default(ep);
327 + ep->e_secinfo_flags[flavor] &= ~mask;
332 --- nfs-utils-1.0.12/utils/exportfs/exportfs.c.orig 2007-02-27 05:55:40.000000000 +0100
333 +++ nfs-utils-1.0.12/utils/exportfs/exportfs.c 2007-03-11 00:39:30.569399317 +0100
334 @@ -376,10 +376,12 @@
339 if (ep->e_flags & NFSEXP_READONLY)
340 c = dumpopt(c, "ro");
342 c = dumpopt(c, "rw");
344 if (ep->e_flags & NFSEXP_ASYNC)
345 c = dumpopt(c, "async");
346 if (ep->e_flags & NFSEXP_GATHERED_WRITES)
351 + secinfo_show(stdout, ep);
352 printf("%c\n", (c != '(')? ')' : ' ');
355 diff -puN utils/exportfs/exports.man~CITI_NFS4_ALL utils/exportfs/exports.man
356 --- nfs-utils-1.0.11/utils/exportfs/exports.man~CITI_NFS4_ALL 2007-02-26 18:52:07.928367000 -0500
357 +++ nfs-utils-1.0.11-kwc/utils/exportfs/exports.man 2007-02-26 18:52:08.691050000 -0500
358 @@ -348,6 +348,20 @@ If the client asks for alternative locat
359 will be given this list of alternatives. (Note that actual replication
360 of the filesystem must be handled elsewhere.)
363 +.IR refer= path@host[+host][:path@host[+host]]
364 +A client referencing the export point will be directed to choose from
365 +the given list an alternative location for the filesystem.
366 +(Note that the server must have a mountpoint here, though a different
367 +filesystem is not required; so, for example,
368 +.IR "mount --bind" " /path /path"
371 +.IR replicas= path@host[+host][:path@host[+host]]
372 +If the client asks for alternative locations for the export point, it
373 +will be given this list of alternatives. (Note that actual replication
374 +of the filesystem must be handled elsewhere.)
379 diff -puN /dev/null utils/mountd/fsloc.c
380 --- /dev/null 2007-02-26 18:43:11.800773059 -0500
381 +++ nfs-utils-1.0.11-kwc/utils/mountd/fsloc.c 2007-02-26 18:52:08.724017000 -0500
384 + * COPYRIGHT (c) 2006
385 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
386 + * ALL RIGHTS RESERVED
388 + * Permission is granted to use, copy, create derivative works
389 + * and redistribute this software and such derivative works
390 + * for any purpose, so long as the name of The University of
391 + * Michigan is not used in any advertising or publicity
392 + * pertaining to the use of distribution of this software
393 + * without specific, written prior authorization. If the
394 + * above copyright notice or any other identification of the
395 + * University of Michigan is included in any copy of any
396 + * portion of this software, then the disclaimer below must
397 + * also be included.
399 + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
400 + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
401 + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
402 + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
403 + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
404 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
405 + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
406 + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
407 + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
408 + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
409 + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
418 +#include "exportfs.h"
420 +/* Debugging tool: prints out @servers info to syslog */
421 +static void replicas_print(struct servers *sp)
425 + xlog(L_NOTICE, "NULL replicas pointer\n");
428 + xlog(L_NOTICE, "replicas listsize=%i\n", sp->h_num);
429 + for (i=0; i<sp->h_num; i++) {
430 + xlog(L_NOTICE, " %s:%s\n",
431 + sp->h_mp[i]->h_host, sp->h_mp[i]->h_path);
436 +/* Called by setting 'Method = stub' in config file. Just returns
437 + * some syntactically correct gibberish for testing purposes.
439 +static struct servers *method_stub(char *key)
441 + struct servers *sp;
442 + struct mount_point *mp;
444 + xlog(L_NOTICE, "called method_stub\n");
445 + sp = malloc(sizeof(struct servers));
448 + mp = calloc(1, sizeof(struct mount_point));
455 + mp->h_host = strdup("stub_server");
456 + mp->h_path = strdup("/my/test/path");
457 + sp->h_referral = 1;
462 +/* Scan @list, which is a NULL-terminated array of strings of the
463 + * form path@host[+host], and return corresponding servers structure.
465 +static struct servers *parse_list(char **list)
468 + struct servers *res;
469 + struct mount_point *mp;
472 + res = malloc(sizeof(struct servers));
477 + /* parse each of the answers in sucession. */
478 + for (i=0; list[i] && i<FSLOC_MAX_LIST; i++) {
479 + mp = calloc(1, sizeof(struct mount_point));
481 + release_replicas(res);
484 + cp = strchr(list[i], '@');
485 + if ((!cp) || list[i][0] != '/') {
486 + xlog(L_WARNING, "invalid entry '%s'", list[i]);
487 + continue; /* XXX Need better error handling */
491 + mp->h_path = strndup(list[i], cp - list[i]);
493 + mp->h_host = strdup(cp);
494 + /* hosts are '+' separated, kernel expects ':' separated */
495 + while ( (cp = strchr(mp->h_host, '+')) )
501 +/* @data is a string of form path@host[+host][:path@host[+host]]
503 +static struct servers *method_list(char *data)
505 + char *copy, *ptr=data;
508 + struct servers *rv=NULL;
510 + xlog(L_NOTICE, "method_list(%s)\n", data);
511 + for (ptr--, listsize=1; ptr; ptr=index(ptr, ':'), listsize++)
513 + list = malloc(listsize * sizeof(char *));
514 + copy = strdup(data);
516 + xlog(L_NOTICE, "converted to %s\n", copy);
517 + if (list && copy) {
519 + for (i=0; i<listsize; i++) {
520 + list[i] = strsep(&ptr, ":");
522 + rv = parse_list(list);
526 + replicas_print(rv);
530 +/* Returns appropriately filled struct servers, or NULL if had a problem */
531 +struct servers *replicas_lookup(int method, char *data, char *key)
533 + struct servers *sp=NULL;
538 + sp = method_list(data);
540 + sp->h_referral = 1;
542 + case FSLOC_REPLICA:
543 + sp = method_list(data);
545 + sp->h_referral = 0;
549 + sp = method_stub(data);
553 + xlog(L_WARNING, "Unknown method = %i", method);
555 + replicas_print(sp);
559 +void release_replicas(struct servers *server)
563 + if (!server) return;
564 + for (i = 0; i < server->h_num; i++) {
565 + free(server->h_mp[i]->h_host);
566 + free(server->h_mp[i]->h_path);
567 + free(server->h_mp[i]);
571 diff -puN /dev/null utils/mountd/fsloc.h
572 --- /dev/null 2007-02-26 18:43:11.800773059 -0500
573 +++ nfs-utils-1.0.11-kwc/utils/mountd/fsloc.h 2007-02-26 18:52:08.764976000 -0500
576 + * COPYRIGHT (c) 2006
577 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN
578 + * ALL RIGHTS RESERVED
580 + * Permission is granted to use, copy, create derivative works
581 + * and redistribute this software and such derivative works
582 + * for any purpose, so long as the name of The University of
583 + * Michigan is not used in any advertising or publicity
584 + * pertaining to the use of distribution of this software
585 + * without specific, written prior authorization. If the
586 + * above copyright notice or any other identification of the
587 + * University of Michigan is included in any copy of any
588 + * portion of this software, then the disclaimer below must
589 + * also be included.
591 + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
592 + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
593 + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
594 + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
595 + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
596 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
597 + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
598 + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
599 + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
600 + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
601 + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
608 +#define FSLOC_MAX_LIST 40
610 +struct mount_point {
617 + struct mount_point *h_mp[FSLOC_MAX_LIST];
618 + int h_referral; /* 0=replica, 1=referral */
621 +struct servers *replicas_lookup(int method, char *data, char *key);
622 +void release_replicas(struct servers *server);
624 +#endif /* FSLOC_H */
625 diff -puN support/include/fstab.h~CITI_NFS4_ALL support/include/fstab.h
626 --- nfs-utils-1.0.11/support/include/fstab.h~CITI_NFS4_ALL 2007-02-26 18:52:09.366915000 -0500
627 +++ nfs-utils-1.0.11-kwc/support/include/fstab.h 2007-02-26 18:52:11.399987000 -0500
630 #include "nfs_mntent.h"
633 +#define _PATH_FSTAB "/etc/fstab"
636 int mtab_is_writable(void);
637 int mtab_does_not_exist(void);
639 @@ -16,6 +20,10 @@ struct mntentchn *getmntoptfile (const c
640 struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
641 struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
643 +struct mntentchn *fstab_head (void);
644 +struct mntentchn *getfsfile (const char *file);
645 +struct mntentchn *getfsspec (const char *spec);
647 void lock_mtab (void);
648 void unlock_mtab (void);
649 void update_mtab (const char *special, nfs_mntent_t *with);
650 diff -puN support/include/nfs_mntent.h~CITI_NFS4_ALL support/include/nfs_mntent.h
651 --- nfs-utils-1.0.11/support/include/nfs_mntent.h~CITI_NFS4_ALL 2007-02-26 18:52:09.630659000 -0500
652 +++ nfs-utils-1.0.11-kwc/support/include/nfs_mntent.h 2007-02-26 18:52:11.440946000 -0500
654 #define _NFS_MNTENT_H
656 typedef struct nfs_mntent_s {
657 - const char *mnt_fsname;
658 - const char *mnt_dir;
659 - const char *mnt_type;
660 - const char *mnt_opts;
668 diff -puN support/nfs/fstab.c~CITI_NFS4_ALL support/nfs/fstab.c
669 --- nfs-utils-1.0.11/support/nfs/fstab.c~CITI_NFS4_ALL 2007-02-26 18:52:09.908463000 -0500
670 +++ nfs-utils-1.0.11-kwc/support/nfs/fstab.c 2007-02-26 18:52:11.493894000 -0500
671 @@ -78,10 +78,10 @@ mtab_is_writable() {
673 /* Contents of mtab and fstab ---------------------------------*/
675 -struct mntentchn mounttable;
676 -static int got_mtab = 0;
677 +struct mntentchn mounttable, fstab;
678 +static int got_mtab = 0, got_fstab = 0;
680 -static void read_mounttable(void);
681 +static void read_mounttable(void), read_fstab(void);
685 @@ -96,6 +96,13 @@ my_free(const void *s) {
697 discard_mntentchn(struct mntentchn *mc0) {
698 struct mntentchn *mc, *mc1;
699 @@ -167,6 +174,26 @@ read_mounttable() {
700 read_mntentchn(mfp, fnam, mc);
705 + mntFILE *mfp = NULL;
707 + struct mntentchn *mc = &fstab;
710 + mc->nxt = mc->prev = NULL;
712 + fnam = _PATH_FSTAB;
713 + mfp = nfs_setmntent (fnam, "r");
714 + if (mfp == NULL || mfp->mntent_fp == NULL) {
716 + error(_("warning: can't open %s: %s"),
717 + _PATH_FSTAB, strerror (errsv));
720 + read_mntentchn(mfp, fnam, mc);
724 * Given the directory name NAME, and the place MCPREV we found it last time,
725 * try to find more occurrences.
726 @@ -201,6 +228,30 @@ getmntdevbackward (const char *name, str
730 +/* Find the dir FILE in fstab. */
732 +getfsfile (const char *file) {
733 + struct mntentchn *mc, *mc0;
735 + mc0 = fstab_head();
736 + for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
737 + if (streq(mc->m.mnt_dir, file))
742 +/* Find the device SPEC in fstab. */
744 +getfsspec (const char *spec) {
745 + struct mntentchn *mc, *mc0;
747 + mc0 = fstab_head();
748 + for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
749 + if (streq(mc->m.mnt_fsname, spec))
754 /* Updating mtab ----------------------------------------------*/
756 /* Flag for already existing lock file. */
757 diff -puN utils/mount/Makefile.am~CITI_NFS4_ALL utils/mount/Makefile.am
758 --- nfs-utils-1.0.11/utils/mount/Makefile.am~CITI_NFS4_ALL 2007-02-26 18:52:10.207463000 -0500
759 +++ nfs-utils-1.0.11-kwc/utils/mount/Makefile.am 2007-02-26 18:52:17.352299000 -0500
761 ## Process this file with automake to produce Makefile.in
765 man8_MANS = mount.nfs.man umount.nfs.man
767 sbin_PROGRAMS = mount.nfs
768 @@ -13,13 +15,14 @@ mount_nfs_LDADD = ../../support/nfs/libn
769 MAINTAINERCLEANFILES = Makefile.in
772 - (cd $(DESTDIR)$(sbindir) && \
773 - ln -sf $(sbin_PROGRAMS) mount.nfs4 && \
774 - ln -sf $(sbin_PROGRAMS) umount.nfs && \
775 - ln -sf $(sbin_PROGRAMS) umount.nfs4)
776 + (chmod +s $(sbin_PROGRAMS) && \
777 + ln -fs $(DESTDIR)$(sbindir)/mount.nfs $(abs_sbindir)/mount.nfs && \
778 + ln -fs $(DESTDIR)$(sbindir)/mount.nfs $(abs_sbindir)/umount.nfs && \
779 + ln -fs $(DESTDIR)$(sbindir)/mount.nfs $(abs_sbindir)/mount.nfs4 && \
780 + ln -fs $(DESTDIR)$(sbindir)/mount.nfs $(abs_sbindir)/umount.nfs4 )
782 - (cd $(DESTDIR)$(sbindir) && \
783 - rm -f mount.nfs4 umount.nfs umount.nfs4)
784 + (cd $(abs_sbindir) && \
785 + rm -f mount.nfs umount.nfs mount.nfs4 umount.nfs4)
789 diff -puN utils/mount/mount.c~CITI_NFS4_ALL utils/mount/mount.c
790 --- nfs-utils-1.0.11/utils/mount/mount.c~CITI_NFS4_ALL 2007-02-26 18:52:10.515323000 -0500
791 +++ nfs-utils-1.0.11-kwc/utils/mount/mount.c 2007-02-26 18:52:16.671458000 -0500
793 #include <sys/mount.h>
800 @@ -43,6 +44,7 @@ char *progname;
806 static struct option longopts[] = {
807 { "fake", 0, 0, 'f' },
808 @@ -74,6 +76,12 @@ struct opt_map {
809 int mask; /* flag mask value */
812 +/* Custom mount options for our own purposes. */
813 +/* Maybe these should now be freed for kernel use again */
814 +#define MS_DUMMY 0x00000000
815 +#define MS_USERS 0x40000000
816 +#define MS_USER 0x20000000
818 static const struct opt_map opt_map[] = {
819 { "defaults", 0, 0, 0 }, /* default options */
820 { "ro", 1, 0, MS_RDONLY }, /* read-only */
821 @@ -90,6 +98,18 @@ static const struct opt_map opt_map[] =
822 { "remount", 0, 0, MS_REMOUNT}, /* Alter flags of mounted FS */
823 { "bind", 0, 0, MS_BIND }, /* Remount part of tree elsewhere */
824 { "rbind", 0, 0, MS_BIND|MS_REC }, /* Idem, plus mounted subtrees */
825 + { "auto", 0, 0, MS_DUMMY }, /* Can be mounted using -a */
826 + { "noauto", 0, 0, MS_DUMMY }, /* Can only be mounted explicitly */
827 + { "users", 0, 0, MS_USERS }, /* Allow ordinary user to mount */
828 + { "nousers", 0, 1, MS_USERS }, /* Forbid ordinary user to mount */
829 + { "user", 0, 0, MS_USER }, /* Allow ordinary user to mount */
830 + { "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */
831 + { "owner", 0, 0, MS_DUMMY }, /* Let the owner of the device mount */
832 + { "noowner", 0, 0, MS_DUMMY }, /* Device owner has no special privs */
833 + { "group", 0, 0, MS_DUMMY }, /* Let the group of the device mount */
834 + { "nogroup", 0, 0, MS_DUMMY }, /* Device group has no special privs */
835 + { "_netdev", 0, 0, MS_DUMMY}, /* Device requires network */
836 + { "comment", 0, 0, MS_DUMMY}, /* fstab comment only (kudzu,_netdev)*/
838 /* add new options here */
840 @@ -104,6 +124,7 @@ static const struct opt_map opt_map[] =
841 { "mand", 0, 0, MS_MANDLOCK }, /* Allow mandatory locks on this FS */
842 { "nomand", 0, 1, MS_MANDLOCK }, /* Forbid mandatory locks on this FS */
844 + { "loop", 1, 0, MS_DUMMY }, /* use a loop device */
846 { "atime", 0, 1, MS_NOATIME }, /* Update access time */
847 { "noatime", 0, 0, MS_NOATIME }, /* Do not update access time */
848 @@ -121,6 +142,12 @@ static char * fix_opts_string (int flags
851 new_opts = xstrdup((flags & MS_RDONLY) ? "ro" : "rw");
852 + if (flags & MS_USER) {
853 + struct passwd *pw = getpwuid(getuid());
855 + new_opts = xstrconcat3(new_opts, ",user=", pw->pw_name);
858 for (om = opt_map; om->opt != NULL; om++) {
861 @@ -132,22 +159,54 @@ static char * fix_opts_string (int flags
862 if (extra_opts && *extra_opts) {
863 new_opts = xstrconcat3(new_opts, ",", extra_opts);
869 +static inline void dup_mntent(struct mntent *ment, nfs_mntent_t *nment)
871 + /* Not sure why nfs_mntent_t should exist */
872 + nment->mnt_fsname = strdup(ment->mnt_fsname);
873 + nment->mnt_dir = strdup(ment->mnt_dir);
874 + nment->mnt_type = strdup(ment->mnt_type);
875 + nment->mnt_opts = strdup(ment->mnt_opts);
876 + nment->mnt_freq = ment->mnt_freq;
877 + nment->mnt_passno = ment->mnt_passno;
880 +free_mntent(nfs_mntent_t *ment, int remount)
882 + free(ment->mnt_fsname);
883 + free(ment->mnt_dir);
884 + free(ment->mnt_type);
886 + * Note: free(ment->mnt_opts) happens in discard_mntentchn()
887 + * via update_mtab() on remouts
890 + free(ment->mnt_opts);
893 int add_mtab(char *fsname, char *mount_point, char *fstype, int flags, char *opts, int freq, int passno)
899 ment.mnt_fsname = fsname;
900 ment.mnt_dir = mount_point;
901 ment.mnt_type = fstype;
902 ment.mnt_opts = fix_opts_string(flags, opts);
904 - ment.mnt_passno= 0;
905 + ment.mnt_freq = freq;
906 + ment.mnt_passno= passno;
908 + if(flags & MS_REMOUNT) {
909 + nfs_mntent_t nment;
911 + dup_mntent(&ment, &nment);
912 + update_mtab(nment.mnt_dir, &nment);
913 + free_mntent(&nment, 1);
919 @@ -191,6 +250,7 @@ void mount_usage()
920 printf("\t-w\t\tMount file system read-write\n");
921 printf("\t-f\t\tFake mount, don't actually mount\n");
922 printf("\t-n\t\tDo not update /etc/mtab\n");
923 + printf("\t-s\t\tTolerate sloppy mount options rather than failing.\n");
924 printf("\t-h\t\tPrint this help\n");
925 printf("\tversion\t\tnfs4 - NFS version 4, nfs - older NFS version supported\n");
926 printf("\tnfsoptions\tRefer mount.nfs(8) or nfs(5)\n\n");
927 @@ -225,52 +285,98 @@ static void parse_opts (const char *opti
929 if (options != NULL) {
930 char *opts = xstrdup(options);
932 - int len = strlen(opts) + 20;
935 + int len = strlen(opts) + 256;
936 + int open_quote = 0;
938 *extra_opts = xmalloc(len);
941 - for (opt = strtok(opts, ","); opt; opt = strtok(NULL, ","))
942 - parse_opt(opt, flags, *extra_opts, len);
944 + for (p=opts, opt=NULL; p && *p; p++) {
946 + opt = p; /* begin of the option item */
948 + open_quote ^= 1; /* reverse the status */
950 + continue; /* still in quoted block */
952 + *p = '\0'; /* terminate the option item */
953 + /* end of option item or last item */
954 + if (*p == '\0' || *(p+1) == '\0') {
955 + parse_opt(opt, flags, *extra_opts, len);
964 + * Look for an option in a comma-separated list
967 +contains(const char *list, const char *s) {
971 + if (strncmp(list, s, n) == 0 &&
972 + (list[n] == 0 || list[n] == ','))
974 + while (*list && *list++ != ',') ;
980 + * If list contains "user=peter" and we ask for "user=", return "peter"
983 +get_value(const char *list, const char *s) {
988 + if (strncmp(list, s, n) == 0) {
990 + while (*s && *s != ',')
992 + return xstrndup(t, s-t);
994 + while (*list && *list++ != ',') ;
999 static void mount_error(char *node)
1003 - printf("%s: mount point %s is not a directory\n", progname, node);
1004 + fprintf(stderr, "%s: mount point %s is not a directory\n", progname, node);
1007 - printf("%s: %s is already mounted or busy\n", progname, node);
1008 + fprintf(stderr, "%s: %s is already mounted or busy\n", progname, node);
1011 - printf("%s: mount point %s does not exist\n", progname, node);
1012 + fprintf(stderr, "%s: mount point %s does not exist\n", progname, node);
1015 - printf("%s: %s\n", progname, strerror(errno));
1016 + fprintf(stderr, "%s: %s\n", progname, strerror(errno));
1019 +#define NFS_MOUNT_VERS_DEFAULT 3
1021 int main(int argc, char *argv[])
1023 - int c, flags = 0, nfs_mount_vers = 0, mnt_err = 1, fake = 0;
1024 + int c, flags = 0, nfs_mount_vers, mnt_err = 1, fake = 0;
1025 char *spec, *mount_point, *extra_opts = NULL;
1026 char *mount_opts = NULL, *p;
1027 + struct mntentchn *mc;
1028 + uid_t uid = getuid();
1031 if ((p = strrchr(progname, '/')) != NULL)
1034 - if (getuid() != 0) {
1035 - printf("%s: only root can do that.\n", progname);
1039 if(!strncmp(progname, "umount", strlen("umount"))) {
1042 @@ -292,7 +398,11 @@ int main(int argc, char *argv[])
1046 - while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:h",
1047 + nfs_mount_vers = NFS_MOUNT_VERS_DEFAULT;
1048 + if (!strcmp(progname, "mount.nfs4"))
1049 + nfs_mount_vers = 4;
1051 + while ((c = getopt_long (argc - 2, argv + 2, "rt:vVwfno:hs",
1052 longopts, NULL)) != -1) {
1055 @@ -322,6 +432,9 @@ int main(int argc, char *argv[])
1057 mount_opts = xstrdup(optarg);
1062 case 128: /* bind */
1063 mounttype = MS_BIND;
1065 @@ -352,31 +465,59 @@ int main(int argc, char *argv[])
1068 mount_point = canonicalize(argv[2]);
1071 parse_opts(mount_opts, &flags, &extra_opts);
1073 - if (!strcmp(progname, "mount.nfs4") || nfs_mount_vers == 4) {
1074 - nfs_mount_vers = 4;
1075 - mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
1076 + if (uid != 0 && !(flags & MS_USERS) && !(flags & MS_USER)) {
1077 + fprintf(stderr, "%s: permission denied\n", progname);
1081 + if ((flags & MS_USER || flags & MS_USERS) && uid != 0) {
1082 + /* check if fstab has entry, and further see if the user or users option is given */
1083 + if ((mc = getfsspec(spec)) == NULL &&
1084 + (mc = getfsfile(spec)) == NULL) {
1085 + fprintf(stderr, "%s: permission denied - invalid option\n", progname);
1089 + if((flags & MS_USER) && !contains(mc->m.mnt_opts, "user")) {
1090 + fprintf(stderr, "%s: permission denied - invalid option\n", progname);
1093 + if((flags & MS_USERS) && !contains(mc->m.mnt_opts, "users")) {
1094 + fprintf(stderr, "%s: permission denied - invalid option\n", progname);
1100 + if (nfs_mount_vers == 4) {
1101 + mnt_err = nfs4mount(spec, mount_point, &flags,
1102 + &extra_opts, &mount_opts, 0);
1105 if (!strcmp(progname, "mount.nfs")) {
1106 mnt_err = nfsmount(spec, mount_point, &flags,
1107 - &extra_opts, &mount_opts, &nfs_mount_vers, 0);
1108 + &extra_opts, &mount_opts, 0);
1116 - if (!mnt_err && !fake) {
1117 - mnt_err = do_mount_syscall(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs", flags, mount_opts);
1120 - mount_error(mount_point);
1123 + mnt_err = do_mount_syscall(spec, mount_point,
1124 + nfs_mount_vers == 4 ? "nfs4" : "nfs", flags, mount_opts);
1127 + mount_error(mount_point);
1132 - add_mtab(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs",
1133 - flags, extra_opts, 0, 0);
1135 + add_mtab(spec, mount_point, nfs_mount_vers == 4 ? "nfs4" : "nfs",
1136 + flags, extra_opts, 0, 0);
1140 diff -puN utils/mount/nfs_mount.h~CITI_NFS4_ALL utils/mount/nfs_mount.h
1141 --- nfs-utils-1.0.11/utils/mount/nfs_mount.h~CITI_NFS4_ALL 2007-02-26 18:52:10.854011000 -0500
1142 +++ nfs-utils-1.0.11-kwc/utils/mount/nfs_mount.h 2007-02-26 18:52:14.652380000 -0500
1143 @@ -78,7 +78,9 @@ struct nfs_mount_data {
1144 #define AUTH_GSS_SPKMP 390011
1147 -int nfsmount(const char *, const char *, int *, char **, char **, int *, int);
1148 +int nfsmount(const char *, const char *, int *, char **, char **, int);
1149 void mount_errors(char *, int, int);
1150 +int contains(const char *, const char *);
1151 +char *get_value(const char *, const char *);
1153 #endif /* _NFS_MOUNT_H */
1154 diff -puN utils/mount/nfsumount.c~CITI_NFS4_ALL utils/mount/nfsumount.c
1155 --- nfs-utils-1.0.11/utils/mount/nfsumount.c~CITI_NFS4_ALL 2007-02-26 18:52:11.207011000 -0500
1156 +++ nfs-utils-1.0.11-kwc/utils/mount/nfsumount.c 2007-02-26 18:52:16.013751000 -0500
1161 +#include <unistd.h>
1164 #include <sys/mount.h>
1168 #include "xcommon.h"
1173 +#include "nfs_mount.h"
1174 #include "mount_constants.h"
1176 #include "nfsumount.h"
1177 @@ -98,9 +101,9 @@ int nfs_call_umount(clnt_addr_t *mnt_ser
1179 mnt_closeclnt(clnt, msock);
1180 if (res == RPC_SUCCESS)
1188 u_int get_mntproto(const char *);
1189 @@ -249,9 +252,6 @@ int add_mtab2(const char *spec, const ch
1194 - * Returns 1 if everything went well, else 0.
1196 int _nfsumount(const char *spec, const char *opts)
1199 @@ -307,8 +307,8 @@ int _nfsumount(const char *spec, const c
1201 return nfs_call_umount(&mnt_server, &dirname);
1203 - printf("%s: %s: not found or not mounted\n", progname, spec);
1205 + fprintf(stderr, "%s: %s: not found / mounted or server not reachable\n", progname, spec);
1209 static struct option umount_longopts[] =
1210 @@ -334,7 +334,7 @@ void umount_usage()
1212 int nfsumount(int argc, char *argv[])
1217 struct mntentchn *mc;
1219 @@ -372,20 +372,33 @@ int nfsumount(int argc, char *argv[])
1220 mc = getmntdirbackward(spec, NULL);
1222 mc = getmntdevbackward(spec, NULL);
1223 - if (!mc && verbose)
1224 - printf(_("Could not find %s in mtab\n"), spec);
1227 - ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts);
1229 - ret = add_mtab2(mc->m.mnt_fsname, mc->m.mnt_dir,
1230 - mc->m.mnt_type, mc->m.mnt_opts, mc);
1232 + fprintf(stderr, "%s: Unable to find '%s' in mount table\n",
1237 - ret = _nfsumount(spec, NULL);
1239 - ret = add_mtab2(spec, spec, spec, spec, NULL);
1240 + if(contains(mc->m.mnt_opts, "user") && getuid() != 0) {
1241 + struct passwd *pw = getpwuid(getuid());
1242 + if(!pw || strcmp(pw->pw_name, get_value(mc->m.mnt_opts, "user="))) {
1243 + fprintf(stderr, "%s: permission denied to unmount %s\n",
1248 + if(!contains(mc->m.mnt_opts, "users") && getuid() != 0) {
1249 + fprintf(stderr, "%s: only root can unmount %s from %s\n",
1250 + progname, mc->m.mnt_fsname, mc->m.mnt_dir);
1254 + v4 = contains(mc->m.mnt_type, "nfs4");
1257 + if(!force && !lazy && !v4)
1258 + ret = _nfsumount(mc->m.mnt_fsname, mc->m.mnt_opts);
1260 + ret = add_mtab2(mc->m.mnt_fsname, mc->m.mnt_dir,
1261 + mc->m.mnt_type, mc->m.mnt_opts, mc);
1265 diff -puN utils/mount/nfs4mount.c~CITI_NFS4_ALL utils/mount/nfs4mount.c
1266 --- nfs-utils-1.0.11/utils/mount/nfs4mount.c~CITI_NFS4_ALL 2007-02-26 18:52:12.678257000 -0500
1267 +++ nfs-utils-1.0.11-kwc/utils/mount/nfs4mount.c 2007-02-26 18:52:13.199107000 -0500
1274 char *IDMAPLCK = DEFAULT_DIR "/rpcidmapd";
1275 #define idmapd_check() do { \
1276 @@ -335,7 +336,7 @@ int nfs4mount(const char *spec, const ch
1278 else if (!strcmp(opt, "ac"))
1281 + else if (!sloppy) {
1282 printf(_("unknown nfs mount option: "
1283 "%s%s\n"), val ? "" : "no", opt);
1285 diff -puN utils/mount/nfsmount.c~CITI_NFS4_ALL utils/mount/nfsmount.c
1286 --- nfs-utils-1.0.11/utils/mount/nfsmount.c~CITI_NFS4_ALL 2007-02-26 18:52:13.028107000 -0500
1287 +++ nfs-utils-1.0.11-kwc/utils/mount/nfsmount.c 2007-02-26 18:52:16.886299000 -0500
1288 @@ -104,6 +104,7 @@ typedef union {
1289 static char errbuf[BUFSIZ];
1290 static char *erreob = &errbuf[BUFSIZ];
1294 /* Convert RPC errors into strings */
1295 int rpc_strerror(int);
1296 @@ -547,15 +548,31 @@ parse_options(char *old_opts, struct nfs
1297 struct pmap *mnt_pmap = &mnt_server->pmap;
1298 struct pmap *nfs_pmap = &nfs_server->pmap;
1300 - char *opt, *opteq;
1301 + char *opt, *opteq, *p, *opt_b;
1302 char *mounthost = NULL;
1304 + int open_quote = 0;
1309 len = strlen(new_opts);
1310 - for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
1311 + for (p=old_opts, opt_b=NULL; p && *p; p++) {
1313 + opt_b = p; /* begin of the option item */
1315 + open_quote ^= 1; /* reverse the status */
1317 + continue; /* still in quoted block */
1319 + *p = '\0'; /* terminate the option item */
1320 + if (*p == '\0' || *(p+1) == '\0') {
1321 + opt = opt_b; /* opt is useful now */
1325 + continue; /* still somewhere in the option item */
1327 if (strlen(opt) >= sizeof(cbuf))
1329 if ((opteq = strchr(opt, '=')) && isdigit(opteq[1])) {
1330 @@ -606,13 +623,13 @@ parse_options(char *old_opts, struct nfs
1331 } else if (!strcmp(opt, "namlen")) {
1332 if (nfs_mount_version >= 2)
1338 } else if (!strcmp(opt, "addr")) {
1342 + } else if (!sloppy)
1344 sprintf(cbuf, "%s=%s,", opt, opteq+1);
1346 @@ -629,7 +646,7 @@ parse_options(char *old_opts, struct nfs
1347 mnt_pmap->pm_prot = IPPROTO_TCP;
1348 data->flags |= NFS_MOUNT_TCP;
1351 + } else if (!sloppy)
1353 #if NFS_MOUNT_VERSION >= 5
1354 } else if (!strcmp(opt, "sec")) {
1355 @@ -658,7 +675,7 @@ parse_options(char *old_opts, struct nfs
1356 data->pseudoflavor = AUTH_GSS_SPKMI;
1357 else if (!strcmp(secflavor, "spkm3p"))
1358 data->pseudoflavor = AUTH_GSS_SPKMP;
1360 + else if (!sloppy) {
1361 printf(_("Warning: Unrecognized security flavor %s.\n"),
1364 @@ -670,14 +687,24 @@ parse_options(char *old_opts, struct nfs
1365 strcspn(opteq+1," \t\n\r,"));
1366 else if (!strcmp(opt, "context")) {
1367 char *context = opteq + 1;
1368 + int ctxlen = strlen(context);
1370 - if (strlen(context) > NFS_MAX_CONTEXT_LEN) {
1371 + if (ctxlen > NFS_MAX_CONTEXT_LEN) {
1372 printf(_("context parameter exceeds limit of %d\n"),
1373 NFS_MAX_CONTEXT_LEN);
1376 - strncpy(data->context, context, NFS_MAX_CONTEXT_LEN);
1378 + /* The context string is in the format of
1379 + * "system_u:object_r:...". We only want
1380 + * the context str between the quotes.
1382 + if (*context == '"')
1383 + strncpy(data->context, context+1,
1386 + strncpy(data->context, context,
1387 + NFS_MAX_CONTEXT_LEN);
1388 + } else if (!sloppy)
1390 sprintf(cbuf, "%s=%s,", opt, opteq+1);
1392 @@ -764,9 +791,11 @@ parse_options(char *old_opts, struct nfs
1396 - printf(_("Unsupported nfs mount option: "
1397 - "%s%s\n"), val ? "" : "no", opt);
1400 + printf(_("Unsupported nfs mount option: "
1401 + "%s%s\n"), val ? "" : "no", opt);
1405 sprintf(cbuf, val ? "%s,":"no%s,", opt);
1407 @@ -815,8 +844,7 @@ nfsmnt_check_compat(const struct pmap *n
1410 nfsmount(const char *spec, const char *node, int *flags,
1411 - char **extra_opts, char **mount_opts, int *nfs_mount_vers,
1413 + char **extra_opts, char **mount_opts, int running_bg)
1415 static char *prev_bg_host;
1417 @@ -847,9 +875,7 @@ nfsmount(const char *spec, const char *n
1419 /* The version to try is either specified or 0
1420 In case it is 0 we tell the caller what we tried */
1421 - if (!*nfs_mount_vers)
1422 - *nfs_mount_vers = find_kernel_nfs_mount_version();
1423 - nfs_mount_version = *nfs_mount_vers;
1424 + nfs_mount_version = find_kernel_nfs_mount_version();
1428 @@ -1090,12 +1116,14 @@ nfsmount(const char *spec, const char *n
1430 flavor = mountres->auth_flavors.auth_flavors_val;
1432 - if (flavor[i] == data.pseudoflavor)
1434 #ifdef NFS_MOUNT_DEBUG
1435 - printf("auth flavor %d: %d\n",
1437 + printf("auth flavor[%d] %d\n", i, flavor[i]);
1439 + if (flavor[i] == data.pseudoflavor ||
1440 + flavor[i] == AUTH_NONE) {
1447 diff -puN support/nfs/conn.c~CITI_NFS4_ALL support/nfs/conn.c
1448 --- nfs-utils-1.0.11/support/nfs/conn.c~CITI_NFS4_ALL 2007-02-26 18:52:15.411170000 -0500
1449 +++ nfs-utils-1.0.11-kwc/support/nfs/conn.c 2007-02-26 18:52:15.506075000 -0500
1450 @@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr
1454 - if (type == SOCK_STREAM || type == SOCK_DGRAM) {
1455 + if (type == SOCK_STREAM) {
1456 cc = connect(so, (struct sockaddr *)saddr, namelen);
1458 rpc_createerr.cf_stat = RPC_SYSTEMERROR;
1459 diff -puN utils/gssd/gssd.c~CITI_NFS4_ALL utils/gssd/gssd.c
1460 --- nfs-utils-1.0.11/utils/gssd/gssd.c~CITI_NFS4_ALL 2007-02-26 18:52:17.909847000 -0500
1461 +++ nfs-utils-1.0.11-kwc/utils/gssd/gssd.c 2007-02-26 18:52:21.146491000 -0500
1463 #include "gss_util.h"
1464 #include "krb5_util.h"
1466 -char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
1467 +char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR;
1468 +char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
1469 char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
1470 char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
1471 int use_memcache = 0;
1472 @@ -111,8 +112,8 @@ main(int argc, char *argv[])
1476 - strncpy(pipefsdir, optarg, sizeof(pipefsdir));
1477 - if (pipefsdir[sizeof(pipefsdir)-1] != '\0')
1478 + strncpy(pipefs_dir, optarg, sizeof(pipefs_dir));
1479 + if (pipefs_dir[sizeof(pipefs_dir)-1] != '\0')
1480 errx(1, "pipefs path name too long");
1483 @@ -130,10 +131,10 @@ main(int argc, char *argv[])
1487 - strncat(pipefsdir + strlen(pipefsdir), "/" GSSD_SERVICE_NAME,
1488 - sizeof(pipefsdir)-strlen(pipefsdir));
1489 - if (pipefsdir[sizeof(pipefsdir)-1] != '\0')
1490 - errx(1, "pipefs path name too long");
1491 + snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
1492 + pipefs_dir, GSSD_SERVICE_NAME);
1493 + if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
1494 + errx(1, "pipefs_nfsdir path name too long");
1496 if ((progname = strrchr(argv[0], '/')))
1498 @@ -161,6 +162,8 @@ main(int argc, char *argv[])
1500 /* Process keytab file and get machine credentials */
1501 gssd_refresh_krb5_machine_creds();
1502 + /* Determine Kerberos information from the kernel */
1503 + gssd_obtain_kernel_krb5_info();
1506 printerr(0, "gssd_run returned!\n");
1507 diff -puN utils/gssd/gssd.h~CITI_NFS4_ALL utils/gssd/gssd.h
1508 --- nfs-utils-1.0.11/utils/gssd/gssd.h~CITI_NFS4_ALL 2007-02-26 18:52:18.243847000 -0500
1509 +++ nfs-utils-1.0.11-kwc/utils/gssd/gssd.h 2007-02-26 18:52:19.072395000 -0500
1510 @@ -58,7 +58,8 @@ enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUT
1514 -extern char pipefsdir[PATH_MAX];
1515 +extern char pipefs_dir[PATH_MAX];
1516 +extern char pipefs_nfsdir[PATH_MAX];
1517 extern char keytabfile[PATH_MAX];
1518 extern char ccachedir[PATH_MAX];
1519 extern int use_memcache;
1520 diff -puN utils/gssd/gssd_main_loop.c~CITI_NFS4_ALL utils/gssd/gssd_main_loop.c
1521 --- nfs-utils-1.0.11/utils/gssd/gssd_main_loop.c~CITI_NFS4_ALL 2007-02-26 18:52:18.584642000 -0500
1522 +++ nfs-utils-1.0.11-kwc/utils/gssd/gssd_main_loop.c 2007-02-26 18:52:19.111395000 -0500
1523 @@ -106,9 +106,9 @@ gssd_run()
1524 dn_act.sa_flags = SA_SIGINFO;
1525 sigaction(DNOTIFY_SIGNAL, &dn_act, NULL);
1527 - if ((fd = open(pipefsdir, O_RDONLY)) == -1) {
1528 + if ((fd = open(pipefs_nfsdir, O_RDONLY)) == -1) {
1529 printerr(0, "ERROR: failed to open %s: %s\n",
1530 - pipefsdir, strerror(errno));
1531 + pipefs_nfsdir, strerror(errno));
1534 fcntl(fd, F_SETSIG, DNOTIFY_SIGNAL);
1535 diff -puN utils/gssd/gssd_proc.c~CITI_NFS4_ALL utils/gssd/gssd_proc.c
1536 --- nfs-utils-1.0.11/utils/gssd/gssd_proc.c~CITI_NFS4_ALL 2007-02-26 18:52:18.936395000 -0500
1537 +++ nfs-utils-1.0.11-kwc/utils/gssd/gssd_proc.c 2007-02-26 18:52:19.165395000 -0500
1539 * with an index into pollarray[], and other basic data about that client.
1541 * Directory structure: created by the kernel nfs client
1542 - * /pipefsdir/clntXX : one per rpc_clnt struct in the kernel
1543 - * /pipefsdir/clntXX/krb5 : read uid for which kernel wants
1544 - * a context, write the resulting context
1545 - * /pipefsdir/clntXX/info : stores info such as server name
1546 + * {pipefs_nfsdir}/clntXX : one per rpc_clnt struct in the kernel
1547 + * {pipefs_nfsdir}/clntXX/krb5 : read uid for which kernel wants
1548 + * a context, write the resulting context
1549 + * {pipefs_nfsdir}/clntXX/info : stores info such as server name
1552 - * Poll all /pipefsdir/clntXX/krb5 files. When ready, data read
1553 + * Poll all {pipefs_nfsdir}/clntXX/krb5 files. When ready, data read
1554 * is a uid; performs rpcsec_gss context initialization protocol to
1555 * get a cred for that user. Writes result to corresponding krb5 file
1556 * in a form the kernel code will understand.
1557 * In addition, we make sure we are notified whenever anything is
1558 - * created or destroyed in pipefsdir/ or in an of the clntXX directories,
1559 - * and rescan the whole pipefsdir when this happens.
1560 + * created or destroyed in {pipefs_nfsdir} or in an of the clntXX directories,
1561 + * and rescan the whole {pipefs_nfsdir} when this happens.
1564 struct pollfd * pollarray;
1565 @@ -389,16 +389,16 @@ update_client_list(void)
1566 struct dirent **namelist;
1569 - if (chdir(pipefsdir) < 0) {
1570 + if (chdir(pipefs_nfsdir) < 0) {
1571 printerr(0, "ERROR: can't chdir to %s: %s\n",
1572 - pipefsdir, strerror(errno));
1573 + pipefs_nfsdir, strerror(errno));
1577 - j = scandir(pipefsdir, &namelist, NULL, alphasort);
1578 + j = scandir(pipefs_nfsdir, &namelist, NULL, alphasort);
1580 printerr(0, "ERROR: can't scandir %s: %s\n",
1581 - pipefsdir, strerror(errno));
1582 + pipefs_nfsdir, strerror(errno));
1585 update_old_clients(namelist, j);
1586 diff -puN support/include/nfslib.h~CITI_NFS4_ALL support/include/nfslib.h
1587 --- nfs-utils-1.0.11/support/include/nfslib.h~CITI_NFS4_ALL 2007-02-26 18:52:19.914943000 -0500
1588 +++ nfs-utils-1.0.11-kwc/support/include/nfslib.h 2007-02-26 18:52:20.001943000 -0500
1589 @@ -57,6 +57,9 @@ enum cle_maptypes {
1593 +#define SECFLAVOR_COUNT 7
1594 +extern char *secflavor_name[SECFLAVOR_COUNT];
1597 * Data related to a single exports entry as returned by getexportent.
1598 * FIXME: export options should probably be parsed at a later time to
1599 @@ -83,6 +86,8 @@ struct exportent {
1603 + int e_secinfo_order[SECFLAVOR_COUNT+1];
1604 + int e_secinfo_flags[SECFLAVOR_COUNT];
1608 @@ -96,6 +101,7 @@ struct rmtabent {
1610 void setexportent(char *fname, char *type);
1611 struct exportent * getexportent(int,int);
1612 +void secinfo_show(FILE *fp, struct exportent *ep);
1613 void putexportent(struct exportent *xep);
1614 void endexportent(void);
1615 struct exportent * mkexportent(char *hname, char *path, char *opts);
1616 diff -puN utils/gssd/krb5_util.c~CITI_NFS4_ALL utils/gssd/krb5_util.c
1617 --- nfs-utils-1.0.11/utils/gssd/krb5_util.c~CITI_NFS4_ALL 2007-02-26 18:52:20.789535000 -0500
1618 +++ nfs-utils-1.0.11-kwc/utils/gssd/krb5_util.c 2007-02-26 18:52:21.202491000 -0500
1621 #include <sys/param.h>
1622 #include <rpc/rpc.h>
1623 +#include <sys/types.h>
1624 #include <sys/stat.h>
1625 #include <sys/socket.h>
1626 #include <arpa/inet.h>
1634 #include <gssapi/gssapi.h>
1635 @@ -123,6 +125,10 @@
1636 /* Global list of principals/cache file names for machine credentials */
1637 struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
1639 +/* Encryption types supported by the kernel rpcsec_gss code */
1640 +int num_krb5_enctypes = 0;
1641 +krb5_enctype *krb5_enctypes = NULL;
1643 /*==========================*/
1644 /*=== Internal routines ===*/
1645 /*==========================*/
1646 @@ -256,56 +262,6 @@ gssd_find_existing_krb5_ccache(uid_t uid
1650 -#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
1652 - * this routine obtains a credentials handle via gss_acquire_cred()
1653 - * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
1654 - * types negotiated.
1656 - * XXX Should call some function to determine the enctypes supported
1657 - * by the kernel. (Only need to do that once!)
1660 - * 0 => all went well
1661 - * -1 => there was an error
1665 -limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
1667 - u_int maj_stat, min_stat;
1668 - gss_cred_id_t credh;
1669 - gss_OID_set_desc desired_mechs;
1670 - krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
1671 - int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
1673 - /* We only care about getting a krb5 cred */
1674 - desired_mechs.count = 1;
1675 - desired_mechs.elements = &krb5oid;
1677 - maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
1678 - &desired_mechs, GSS_C_INITIATE,
1679 - &credh, NULL, NULL);
1681 - if (maj_stat != GSS_S_COMPLETE) {
1682 - pgsserr("gss_acquire_cred",
1683 - maj_stat, min_stat, &krb5oid);
1687 - maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
1688 - num_enctypes, &enctypes);
1689 - if (maj_stat != GSS_S_COMPLETE) {
1690 - pgsserr("gss_set_allowable_enctypes",
1691 - maj_stat, min_stat, &krb5oid);
1694 - sec->cred = credh;
1698 -#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
1701 * Obtain credentials via a key in the keytab given
1702 * a keytab handle and a gssd_k5_kt_princ structure.
1703 @@ -609,6 +565,56 @@ gssd_set_krb5_ccache_name(char *ccname)
1708 + * Parse the supported encryption type information
1711 +parse_enctypes(char *enctypes)
1714 + char *curr, *comma;
1717 + /* Just in case this ever gets called more than once */
1718 + if (krb5_enctypes != NULL) {
1719 + free(krb5_enctypes);
1720 + krb5_enctypes = NULL;
1721 + num_krb5_enctypes = 0;
1724 + /* count the number of commas */
1725 + for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
1726 + comma = strchr(curr, ',');
1727 + if (comma != NULL)
1732 + /* If no more commas and we're not at the end, there's one more value */
1733 + if (*curr != '\0')
1736 + /* Empty string, return an error */
1740 + /* Allocate space for enctypes array */
1741 + if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
1745 + /* Now parse each value into the array */
1746 + for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
1747 + krb5_enctypes[i++] = atoi(curr);
1748 + comma = strchr(curr, ',');
1749 + if (comma == NULL)
1753 + num_krb5_enctypes = n;
1757 /*==========================*/
1758 /*=== External routines ===*/
1759 /*==========================*/
1760 @@ -860,3 +866,125 @@ gssd_destroy_krb5_machine_creds(void)
1761 krb5_free_context(context);
1764 +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
1766 + * this routine obtains a credentials handle via gss_acquire_cred()
1767 + * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
1768 + * types negotiated.
1771 + * 0 => all went well
1772 + * -1 => there was an error
1776 +limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
1778 + u_int maj_stat, min_stat;
1779 + gss_cred_id_t credh;
1780 + gss_OID_set_desc desired_mechs;
1781 + krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC};
1782 + int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
1784 + /* We only care about getting a krb5 cred */
1785 + desired_mechs.count = 1;
1786 + desired_mechs.elements = &krb5oid;
1788 + maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
1789 + &desired_mechs, GSS_C_INITIATE,
1790 + &credh, NULL, NULL);
1792 + if (maj_stat != GSS_S_COMPLETE) {
1793 + pgsserr("gss_acquire_cred",
1794 + maj_stat, min_stat, &krb5oid);
1799 + * If we failed for any reason to produce global
1800 + * list of supported enctypes, use local default here.
1802 + if (krb5_enctypes == NULL)
1803 + maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
1804 + &krb5oid, num_enctypes, &enctypes);
1806 + maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
1807 + &krb5oid, num_krb5_enctypes,
1809 + if (maj_stat != GSS_S_COMPLETE) {
1810 + pgsserr("gss_set_allowable_enctypes",
1811 + maj_stat, min_stat, &krb5oid);
1814 + sec->cred = credh;
1818 +#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
1821 + * Obtain supported enctypes from kernel.
1822 + * Set defaults if info is not available.
1825 +gssd_obtain_kernel_krb5_info(void)
1827 + char enctype_file_name[128];
1829 + char enctypes[128];
1832 + int use_default_enctypes = 0;
1833 + int nbytes, numfields;
1834 + char default_enctypes[] = "1,3,2";
1837 + snprintf(enctype_file_name, sizeof(enctype_file_name),
1838 + "%s/%s", pipefs_dir, "krb5_info");
1840 + if ((fd = open(enctype_file_name, O_RDONLY)) == -1) {
1841 + printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: "
1842 + "Unable to open '%s'. Unable to determine "
1843 + "Kerberos encryption types supported by the "
1844 + "kernel; using defaults (%s).\n",
1845 + enctype_file_name, default_enctypes);
1846 + use_default_enctypes = 1;
1847 + goto do_the_parse;
1849 + memset(buf, 0, sizeof(buf));
1850 + if ((nbytes = read(fd, buf, sizeof(buf)-1)) == -1) {
1851 + printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
1852 + "Error reading Kerberos encryption type "
1853 + "information file '%s'; using defaults (%s).\n",
1854 + enctype_file_name, default_enctypes);
1855 + use_default_enctypes = 1;
1857 + goto do_the_parse;
1860 + numfields = sscanf(buf, "enctypes: %s\n%n", enctypes, &nscanned);
1861 + if (numfields < 1) {
1862 + printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
1863 + "error parsing Kerberos encryption type "
1864 + "information from file '%s'; using defaults (%s).\n",
1865 + enctype_file_name, default_enctypes);
1866 + use_default_enctypes = 1;
1867 + goto do_the_parse;
1869 + if (nbytes > nscanned) {
1870 + printerr(2, "gssd_obtain_kernel_krb5_info: "
1871 + "Ignoring extra information, '%s', from '%s'\n",
1872 + buf+nscanned, enctype_file_name);
1873 + goto do_the_parse;
1876 + if (use_default_enctypes)
1877 + strcpy(enctypes, default_enctypes);
1879 + if ((code = parse_enctypes(enctypes)) != 0) {
1880 + printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: "
1881 + "parse_enctypes%s failed with code %d\n",
1882 + use_default_enctypes ? " (with default enctypes)" : "",
1886 diff -puN utils/gssd/krb5_util.h~CITI_NFS4_ALL utils/gssd/krb5_util.h
1887 --- nfs-utils-1.0.11/utils/gssd/krb5_util.h~CITI_NFS4_ALL 2007-02-26 18:52:21.065491000 -0500
1888 +++ nfs-utils-1.0.11-kwc/utils/gssd/krb5_util.h 2007-02-26 18:52:21.305491000 -0500
1889 @@ -22,6 +22,8 @@ int gssd_refresh_krb5_machine_creds(voi
1890 void gssd_free_krb5_machine_cred_list(char **list);
1891 void gssd_setup_krb5_machine_gss_ccache(char *servername);
1892 void gssd_destroy_krb5_machine_creds(void);
1893 +void gssd_obtain_kernel_krb5_info(void);
1896 #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
1897 int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid);
1898 diff -puN utils/gssd/context.h~CITI_NFS4_ALL utils/gssd/context.h
1899 --- nfs-utils-1.0.11/utils/gssd/context.h~CITI_NFS4_ALL 2007-02-26 18:52:21.831041000 -0500
1900 +++ nfs-utils-1.0.11-kwc/utils/gssd/context.h 2007-02-26 18:52:22.471949000 -0500
1903 - Copyright (c) 2004 The Regents of the University of Michigan.
1904 + Copyright (c) 2004-2006 The Regents of the University of Michigan.
1905 All rights reserved.
1907 Redistribution and use in source and binary forms, with or without
1909 /* Hopefully big enough to hold any serialized context */
1910 #define MAX_CTX_LEN 4096
1912 +/* New context format flag values */
1913 +#define KRB5_CTX_FLAG_INITIATOR 0x00000001
1914 +#define KRB5_CTX_FLAG_CFX 0x00000002
1915 +#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
1917 int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf,
1919 diff -puN utils/gssd/context_lucid.c~CITI_NFS4_ALL utils/gssd/context_lucid.c
1920 --- nfs-utils-1.0.11/utils/gssd/context_lucid.c~CITI_NFS4_ALL 2007-02-26 18:52:22.123039000 -0500
1921 +++ nfs-utils-1.0.11-kwc/utils/gssd/context_lucid.c 2007-02-26 18:52:22.513907000 -0500
1927 #include "gss_util.h"
1928 #include "gss_oids.h"
1929 #include "err_util.h"
1930 @@ -113,15 +114,13 @@ prepare_krb5_rfc1964_buffer(gss_krb5_luc
1931 * Note that the rfc1964 version only supports DES enctypes.
1933 if (lctx->rfc1964_kd.ctx_key.type != 4) {
1934 - printerr(1, "prepare_krb5_rfc1964_buffer: "
1935 - "overriding heimdal keytype (%d => %d)\n",
1936 - lctx->rfc1964_kd.ctx_key.type, 4);
1937 + printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
1938 + __FUNCTION__, lctx->rfc1964_kd.ctx_key.type, 4);
1939 lctx->rfc1964_kd.ctx_key.type = 4;
1942 - printerr(2, "prepare_krb5_rfc1964_buffer: serializing keys with "
1943 - "enctype %d and length %d\n",
1944 - lctx->rfc1964_kd.ctx_key.type,
1945 + printerr(2, "%s: serializing keys with enctype %d and length %d\n",
1946 + __FUNCTION__, lctx->rfc1964_kd.ctx_key.type,
1947 lctx->rfc1964_kd.ctx_key.length);
1949 /* derive the encryption key and copy it into buffer */
1950 @@ -152,15 +151,361 @@ out_err:
1955 -prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx,
1956 - gss_buffer_desc *buf)
1957 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1958 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1961 +#define KG_USAGE_SEAL 22
1962 +#define KG_USAGE_SIGN 23
1963 +#define KG_USAGE_SEQ 24
1966 +#define KG_USAGE_ACCEPTOR_SEAL 22
1967 +#define KG_USAGE_ACCEPTOR_SIGN 23
1968 +#define KG_USAGE_INITIATOR_SEAL 24
1969 +#define KG_USAGE_INITIATOR_SIGN 25
1971 +/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
1973 + SEAL_ALG_NONE = 0xffff,
1974 + SEAL_ALG_DES = 0x0000,
1975 + SEAL_ALG_1 = 0x0001, /* not published */
1976 + SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */
1977 + SEAL_ALG_DES3KD = 0x0002
1980 +#define KEY_USAGE_SEED_ENCRYPTION 0xAA
1981 +#define KEY_USAGE_SEED_INTEGRITY 0x55
1982 +#define KEY_USAGE_SEED_CHECKSUM 0x99
1983 +#define K5CLENGTH 5
1985 +/* Flags for version 2 context flags */
1986 +#define KRB5_CTX_FLAG_INITIATOR 0x00000001
1987 +#define KRB5_CTX_FLAG_CFX 0x00000002
1988 +#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
1990 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1991 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
1993 + * We don't have "legal" access to these MIT-only
1994 + * structures located in libk5crypto
1996 +extern void krb5int_enc_arcfour;
1997 +extern void krb5int_enc_des3;
1998 +extern void krb5int_enc_aes128;
1999 +extern void krb5int_enc_aes256;
2000 +extern int krb5_derive_key();
2003 +key_lucid_to_krb5(const gss_krb5_lucid_key_t *lin, krb5_keyblock *kout)
2005 - printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n");
2007 + memset(kout, '\0', sizeof(kout));
2009 + kout->enctype = lin->type;
2010 + kout->length = lin->length;
2011 + kout->contents = lin->data;
2013 + kout->keytype = lin->type;
2014 + kout->keyvalue.length = lin->length;
2015 + kout->keyvalue.data = lin->data;
2020 +key_krb5_to_lucid(const krb5_keyblock *kin, gss_krb5_lucid_key_t *lout)
2022 + memset(lout, '\0', sizeof(lout));
2024 + lout->type = kin->enctype;
2025 + lout->length = kin->length;
2026 + lout->data = kin->contents;
2028 + lout->type = kin->keytype;
2029 + lout->length = kin->keyvalue.length;
2030 + memcpy(lout->data, kin->keyvalue.data, kin->keyvalue.length);
2034 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
2035 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
2036 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
2037 +/* XXX Hack alert! XXX Do NOT submit upstream! XXX */
2039 + * Function to derive a new key from a given key and given constant data.
2041 +static krb5_error_code
2042 +derive_key_lucid(const gss_krb5_lucid_key_t *in, gss_krb5_lucid_key_t *out,
2043 + int usage, char extra)
2045 + krb5_error_code code;
2046 + unsigned char constant_data[K5CLENGTH];
2050 + krb5_keyblock kin, kout; /* must send krb5_keyblock, not lucid! */
2051 +#ifdef HAVE_HEIMDAL
2052 + krb5_context kcontext;
2053 + krb5_keyblock *outkey;
2057 + * XXX Hack alert. We don't have "legal" access to these
2058 + * values and structures located in libk5crypto
2060 + switch (in->type) {
2061 + case ENCTYPE_DES3_CBC_SHA1:
2063 + case ENCTYPE_DES3_CBC_RAW:
2067 + enc = &krb5int_enc_des3;
2070 + case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
2073 + enc = &krb5int_enc_aes128;
2076 + case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
2079 + enc = &krb5int_enc_aes256;
2083 + code = KRB5_BAD_ENCTYPE;
2087 + /* allocate memory for output key */
2088 + if ((out->data = malloc(keylength)) == NULL) {
2092 + out->length = keylength;
2093 + out->type = in->type;
2095 + /* Convert to correct format for call to krb5_derive_key */
2096 + key_lucid_to_krb5(in, &kin);
2097 + key_lucid_to_krb5(out, &kout);
2099 + datain.data = (char *) constant_data;
2100 + datain.length = K5CLENGTH;
2102 + ((char *)(datain.data))[0] = (usage>>24)&0xff;
2103 + ((char *)(datain.data))[1] = (usage>>16)&0xff;
2104 + ((char *)(datain.data))[2] = (usage>>8)&0xff;
2105 + ((char *)(datain.data))[3] = usage&0xff;
2107 + ((char *)(datain.data))[4] = (char) extra;
2110 + code = krb5_derive_key(enc, &kin, &kout, &datain);
2112 + if ((code = krb5_init_context(&kcontext))) {
2114 + code = krb5_derive_key(kcontext, &kin, in->type, constant_data, K5CLENGTH, &outkey);
2122 + key_krb5_to_lucid(&kout, out);
2124 + key_krb5_to_lucid(outkey, out);
2125 + krb5_free_keyblock(kcontext, outkey);
2126 + krb5_free_context(kcontext);
2131 + printerr(0, "ERROR: %s: returning error %d (%s)\n",
2132 + __FUNCTION__, code, error_message(code));
2138 + * Prepare a new-style buffer, as defined in rfc4121 (a.k.a. cfx),
2139 + * to send to the kernel for newer encryption types -- or for DES3.
2141 + * The new format is:
2143 + * u32 initiate; ( whether we are the initiator or not )
2146 + * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
2147 + * #define KRB5_CTX_FLAG_CFX 0x00000002
2148 + * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
2150 + * u32 enctype; ( encrption type of keys )
2151 + * u32 size_of_each_key; ( size of each key in bytes )
2152 + * u32 number_of_keys; ( N -- should always be 3 for now )
2153 + * keydata-1; ( Ke )
2154 + * keydata-2; ( Ki )
2155 + * keydata-3; ( Kc )
2159 +prepare_krb5_rfc4121_buffer(gss_krb5_lucid_context_v1_t *lctx,
2160 + gss_buffer_desc *buf)
2163 + uint32_t v2_flags = 0;
2164 + gss_krb5_lucid_key_t enc_key;
2165 + gss_krb5_lucid_key_t derived_key;
2166 + gss_buffer_desc fakeoid;
2171 + memset(&enc_key, 0, sizeof(enc_key));
2172 + memset(&fakeoid, 0, sizeof(fakeoid));
2174 + if (!(buf->value = calloc(1, MAX_CTX_LEN)))
2177 + end = buf->value + MAX_CTX_LEN;
2180 + if (WRITE_BYTES(&p, end, lctx->initiate)) goto out_err;
2181 + if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err;
2183 + if (lctx->initiate)
2184 + v2_flags |= KRB5_CTX_FLAG_INITIATOR;
2185 + if (lctx->protocol != 0)
2186 + v2_flags |= KRB5_CTX_FLAG_CFX;
2187 + if (lctx->protocol != 0 && lctx->cfx_kd.have_acceptor_subkey == 1)
2188 + v2_flags |= KRB5_CTX_FLAG_ACCEPTOR_SUBKEY;
2190 + if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
2192 + if (WRITE_BYTES(&p, end, lctx->send_seq)) goto out_err;
2194 + /* Protocol 0 here implies DES3 or RC4 */
2195 + printerr(2, "%s: protocol %d\n", __FUNCTION__, lctx->protocol);
2196 + if (lctx->protocol == 0) {
2197 + enctype = lctx->rfc1964_kd.ctx_key.type;
2198 +#ifdef HAVE_HEIMDAL
2200 + * The kernel gss code expects ENCTYPE_DES3_CBC_RAW (6) for
2201 + * 3des keys, but Heimdal key has ENCTYPE_DES3_CBC_SHA1 (16).
2202 + * Force the Heimdal enctype to 6.
2204 + if (enctype == ENCTYPE_DES3_CBC_SHA1) {
2205 + printerr(2, "%s: overriding heimdal keytype (%d => %d)\n",
2206 + __FUNCTION__, enctype, 6);
2211 + keysize = lctx->rfc1964_kd.ctx_key.length;
2212 + numkeys = 3; /* XXX is always gonna be three? */
2214 + if (lctx->cfx_kd.have_acceptor_subkey) {
2215 + enctype = lctx->cfx_kd.acceptor_subkey.type;
2216 + keysize = lctx->cfx_kd.acceptor_subkey.length;
2218 + enctype = lctx->cfx_kd.ctx_key.type;
2219 + keysize = lctx->cfx_kd.ctx_key.length;
2223 + printerr(2, "%s: serializing %d keys with enctype %d and size %d\n",
2224 + __FUNCTION__, numkeys, enctype, keysize);
2225 + if (WRITE_BYTES(&p, end, enctype)) goto out_err;
2226 + if (WRITE_BYTES(&p, end, keysize)) goto out_err;
2227 + if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
2229 + if (lctx->protocol == 0) {
2230 + /* derive and send down: Ke, Ki, and Kc */
2232 + if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
2233 + lctx->rfc1964_kd.ctx_key.length))
2237 + if (write_bytes(&p, end, lctx->rfc1964_kd.ctx_key.data,
2238 + lctx->rfc1964_kd.ctx_key.length))
2242 + if (derive_key_lucid(&lctx->rfc1964_kd.ctx_key,
2244 + KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
2246 + if (write_bytes(&p, end, derived_key.data,
2247 + derived_key.length))
2249 + free(derived_key.data);
2251 + gss_krb5_lucid_key_t *keyptr;
2252 + uint32_t sign_usage, seal_usage;
2254 + if (lctx->cfx_kd.have_acceptor_subkey)
2255 + keyptr = &lctx->cfx_kd.acceptor_subkey;
2257 + keyptr = &lctx->cfx_kd.ctx_key;
2259 + if (lctx->initiate == 1) {
2260 + sign_usage = KG_USAGE_INITIATOR_SIGN;
2261 + seal_usage = KG_USAGE_INITIATOR_SEAL;
2263 + sign_usage = KG_USAGE_ACCEPTOR_SIGN;
2264 + seal_usage = KG_USAGE_ACCEPTOR_SEAL;
2267 + /* derive and send down: Ke, Ki, and Kc */
2270 + if (derive_key_lucid(keyptr, &derived_key,
2271 + seal_usage, KEY_USAGE_SEED_ENCRYPTION))
2273 + if (write_bytes(&p, end, derived_key.data,
2274 + derived_key.length))
2276 + free(derived_key.data);
2279 + if (derive_key_lucid(keyptr, &derived_key,
2280 + seal_usage, KEY_USAGE_SEED_INTEGRITY))
2282 + if (write_bytes(&p, end, derived_key.data,
2283 + derived_key.length))
2285 + free(derived_key.data);
2288 + if (derive_key_lucid(keyptr, &derived_key,
2289 + sign_usage, KEY_USAGE_SEED_CHECKSUM))
2291 + if (write_bytes(&p, end, derived_key.data,
2292 + derived_key.length))
2294 + free(derived_key.data);
2297 + buf->length = p - (char *)buf->value;
2301 + printerr(0, "ERROR: %s: failed serializing krb5 context for kernel\n",
2305 + buf->value = NULL;
2308 + if (enc_key.data) {
2309 + free(enc_key.data);
2310 + enc_key.data = NULL;
2315 serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf)
2317 @@ -170,7 +515,7 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
2318 gss_krb5_lucid_context_v1_t *lctx = 0;
2321 - printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n");
2322 + printerr(2, "DEBUG: %s: lucid version!\n", __FUNCTION__);
2323 maj_stat = gss_export_lucid_sec_context(&min_stat, &ctx,
2325 if (maj_stat != GSS_S_COMPLETE) {
2326 @@ -192,11 +537,20 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
2330 - /* Now lctx points to a lucid context that we can send down to kernel */
2331 - if (lctx->protocol == 0)
2333 + * Now lctx points to a lucid context that we can send down to kernel
2335 + * Note: we send down different information to the kernel depending
2336 + * on the protocol version and the enctyption type.
2337 + * For protocol version 0 with all enctypes besides DES3, we use
2338 + * the original format. For protocol version != 0 or DES3, we
2339 + * send down the new style information.
2342 + if (lctx->protocol == 0 && lctx->rfc1964_kd.ctx_key.type <= 4)
2343 retcode = prepare_krb5_rfc1964_buffer(lctx, buf);
2345 - retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf);
2346 + retcode = prepare_krb5_rfc4121_buffer(lctx, buf);
2348 maj_stat = gss_free_lucid_sec_context(&min_stat, ctx, return_ctx);
2349 if (maj_stat != GSS_S_COMPLETE) {
2350 @@ -206,8 +560,8 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
2354 - printerr(1, "serialize_krb5_ctx: prepare_krb5_*_buffer "
2355 - "failed (retcode = %d)\n", retcode);
2356 + printerr(1, "%s: prepare_krb5_*_buffer failed (retcode = %d)\n",
2357 + __FUNCTION__, retcode);
2361 @@ -217,4 +571,7 @@ out_err:
2362 printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
2368 #endif /* HAVE_LUCID_CONTEXT_SUPPORT */
2369 diff -puN utils/gssd/context_mit.c~CITI_NFS4_ALL utils/gssd/context_mit.c
2370 --- nfs-utils-1.0.11/utils/gssd/context_mit.c~CITI_NFS4_ALL 2007-02-26 18:52:22.399022000 -0500
2371 +++ nfs-utils-1.0.11-kwc/utils/gssd/context_mit.c 2007-02-26 18:52:22.561859000 -0500
2374 - Copyright (c) 2004 The Regents of the University of Michigan.
2375 + Copyright (c) 2004-2006 The Regents of the University of Michigan.
2376 All rights reserved.
2378 Redistribution and use in source and binary forms, with or without
2385 #include <rpc/rpc.h>
2386 #include <rpc/auth_gss.h>
2388 /* XXX argggg, there's gotta be a better way than just duplicating this
2389 * whole struct. Unfortunately, this is in a "private" header file,
2390 * so this is our best choice at this point :-/
2392 - * XXX Does this match the Heimdal definition? */
2395 typedef struct _krb5_gss_ctx_id_rec {
2396 unsigned int initiate : 1; /* nonzero if initiating, zero if accepting */
2397 @@ -139,6 +139,124 @@ write_keyblock(char **p, char *end, stru
2401 + * XXX Hack alert! XXX Do NOT submit upstream!
2402 + * XXX Hack alert! XXX Do NOT submit upstream!
2404 + * We shouldn't be using these definitions
2406 + * XXX Hack alert! XXX Do NOT submit upstream!
2407 + * XXX Hack alert! XXX Do NOT submit upstream!
2410 +#define KG_USAGE_SEAL 22
2411 +#define KG_USAGE_SIGN 23
2412 +#define KG_USAGE_SEQ 24
2415 +#define KG_USAGE_ACCEPTOR_SEAL 22
2416 +#define KG_USAGE_ACCEPTOR_SIGN 23
2417 +#define KG_USAGE_INITIATOR_SEAL 24
2418 +#define KG_USAGE_INITIATOR_SIGN 25
2420 +/* Lifted from mit src/lib/gssapi/krb5/gssapiP_krb5.h */
2422 + SEAL_ALG_NONE = 0xffff,
2423 + SEAL_ALG_DES = 0x0000,
2424 + SEAL_ALG_1 = 0x0001, /* not published */
2425 + SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; */
2426 + SEAL_ALG_DES3KD = 0x0002
2429 +#define KEY_USAGE_SEED_ENCRYPTION 0xAA
2430 +#define KEY_USAGE_SEED_INTEGRITY 0x55
2431 +#define KEY_USAGE_SEED_CHECKSUM 0x99
2432 +#define K5CLENGTH 5
2434 +extern void krb5_enc_des3;
2435 +extern void krb5int_enc_des3;
2436 +extern void krb5int_enc_arcfour;
2437 +extern void krb5int_enc_aes128;
2438 +extern void krb5int_enc_aes256;
2439 +extern int krb5_derive_key();
2442 + * XXX Hack alert! XXX Do NOT submit upstream!
2443 + * XXX Hack alert! XXX Do NOT submit upstream!
2445 + * We should be passing down a single key to the kernel
2446 + * and it should be deriving the other keys. We cannot
2447 + * depend on any of this stuff being accessible in the
2450 + * XXX Hack alert! XXX Do NOT submit upstream!
2451 + * XXX Hack alert! XXX Do NOT submit upstream!
2454 + * Function to derive a new key from a given key and given constant data.
2456 +static krb5_error_code
2457 +derive_key(const krb5_keyblock *in, krb5_keyblock *out, int usage, char extra)
2459 + krb5_error_code code;
2460 + unsigned char constant_data[K5CLENGTH];
2465 + switch (in->enctype) {
2466 +#ifdef ENCTYPE_DES3_CBC_RAW
2467 + case ENCTYPE_DES3_CBC_RAW:
2469 +/* Extra hack, the structure was renamed as rc4 was added... */
2470 +#if defined(ENCTYPE_ARCFOUR_HMAC)
2471 + enc = &krb5int_enc_des3;
2473 + enc = &krb5_enc_des3;
2477 +#ifdef ENCTYPE_ARCFOUR_HMAC
2478 + case ENCTYPE_ARCFOUR_HMAC:
2480 + enc = &krb5int_enc_arcfour;
2484 + code = KRB5_BAD_ENCTYPE;
2488 + /* allocate memory for output key */
2489 + if ((out->contents = malloc(keylength)) == NULL) {
2493 + out->length = keylength;
2494 + out->enctype = in->enctype;
2496 + datain.data = (char *) constant_data;
2497 + datain.length = K5CLENGTH;
2499 + datain.data[0] = (usage>>24)&0xff;
2500 + datain.data[1] = (usage>>16)&0xff;
2501 + datain.data[2] = (usage>>8)&0xff;
2502 + datain.data[3] = usage&0xff;
2504 + datain.data[4] = (char) extra;
2506 + if ((code = krb5_derive_key(enc, in, out, &datain))) {
2507 + free(out->contents);
2508 + out->contents = NULL;
2513 + printerr(0, "ERROR: derive_key returning error %d (%s)\n",
2514 + code, error_message(code));
2519 * We really shouldn't know about glue-layer context structure, but
2520 * we need to get at the real krb5 context pointer. This should be
2521 * removed as soon as we say there is no support for MIT Kerberos
2522 @@ -154,48 +272,124 @@ serialize_krb5_ctx(gss_ctx_id_t ctx, gss
2524 krb5_gss_ctx_id_t kctx = ((gss_union_ctx_id_t)ctx)->internal_ctx_id;
2526 - static int constant_one = 1;
2527 static int constant_zero = 0;
2528 + static int constant_one = 1;
2529 + static int constant_two = 2;
2530 uint32_t word_seq_send;
2531 + u_int64_t seq_send_64bit;
2532 + uint32_t v2_flags = 0;
2533 + krb5_keyblock derived_key;
2536 if (!(buf->value = calloc(1, MAX_CTX_LEN)))
2539 end = buf->value + MAX_CTX_LEN;
2541 - if (kctx->initiate) {
2542 - if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
2545 - if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
2547 - if (kctx->seed_init) {
2548 - if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
2551 - if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
2553 - if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
2554 + switch (kctx->sealalg) {
2555 + case SEAL_ALG_DES:
2556 + /* Old format of context to the kernel */
2557 + if (kctx->initiate) {
2558 + if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
2561 + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
2563 + if (kctx->seed_init) {
2564 + if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
2567 + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
2569 + if (write_bytes(&p, end, &kctx->seed, sizeof(kctx->seed)))
2571 + if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
2572 + if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
2573 + if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
2574 + word_seq_send = kctx->seq_send;
2575 + if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
2576 + if (write_oid(&p, end, kctx->mech_used)) goto out_err;
2578 + printerr(2, "serialize_krb5_ctx: serializing keys with "
2579 + "enctype %d and length %d\n",
2580 + kctx->enc->enctype, kctx->enc->length);
2582 + if (write_keyblock(&p, end, kctx->enc)) goto out_err;
2583 + if (write_keyblock(&p, end, kctx->seq)) goto out_err;
2585 + case SEAL_ALG_MICROSOFT_RC4:
2586 + case SEAL_ALG_DES3KD:
2587 + /* New format of context to the kernel */
2590 + * #define KRB5_CTX_FLAG_INITIATOR 0x00000001
2591 + * #define KRB5_CTX_FLAG_CFX 0x00000002
2592 + * #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
2595 + * u32 size_of_each_key; ( size in bytes )
2596 + * u32 number_of_keys; ( N (assumed to be 3 for now) )
2597 + * keydata-1; ( Ke (Kenc for DES3) )
2598 + * keydata-2; ( Ki (Kseq for DES3) )
2599 + * keydata-3; ( Kc (derived checksum key) )
2601 + if (kctx->initiate) {
2602 + if (WRITE_BYTES(&p, end, constant_one)) goto out_err;
2605 + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err;
2607 + if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
2609 + /* Only applicable flag for this is initiator */
2610 + if (kctx->initiate) v2_flags |= KRB5_CTX_FLAG_INITIATOR;
2611 + if (WRITE_BYTES(&p, end, v2_flags)) goto out_err;
2613 + seq_send_64bit = kctx->seq_send;
2614 + if (WRITE_BYTES(&p, end, seq_send_64bit)) goto out_err;
2616 + if (WRITE_BYTES(&p, end, kctx->enc->enctype)) goto out_err;
2617 + if (WRITE_BYTES(&p, end, kctx->enc->length)) goto out_err;
2619 + if (WRITE_BYTES(&p, end, numkeys)) goto out_err;
2620 + printerr(2, "serialize_krb5_ctx: serializing %d keys with "
2621 + "enctype %d and size %d\n",
2622 + numkeys, kctx->enc->enctype, kctx->enc->length);
2625 + if (write_bytes(&p, end, kctx->enc->contents,
2626 + kctx->enc->length))
2630 + if (write_bytes(&p, end, kctx->enc->contents,
2631 + kctx->enc->length))
2635 + if (derive_key(kctx->seq, &derived_key,
2636 + KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM))
2638 + if (write_bytes(&p, end, derived_key.contents,
2639 + derived_key.length))
2641 + free(derived_key.contents);
2644 + printerr(0, "ERROR: serialize_krb5_ctx: unsupported seal "
2645 + "algorithm %d\n", kctx->sealalg);
2647 - if (WRITE_BYTES(&p, end, kctx->signalg)) goto out_err;
2648 - if (WRITE_BYTES(&p, end, kctx->sealalg)) goto out_err;
2649 - if (WRITE_BYTES(&p, end, kctx->endtime)) goto out_err;
2650 - word_seq_send = kctx->seq_send;
2651 - if (WRITE_BYTES(&p, end, word_seq_send)) goto out_err;
2652 - if (write_oid(&p, end, kctx->mech_used)) goto out_err;
2654 - printerr(2, "serialize_krb5_ctx: serializing keys with "
2655 - "enctype %d and length %d\n",
2656 - kctx->enc->enctype, kctx->enc->length);
2658 - if (write_keyblock(&p, end, kctx->enc)) goto out_err;
2659 - if (write_keyblock(&p, end, kctx->seq)) goto out_err;
2662 buf->length = p - (char *)buf->value;
2666 printerr(0, "ERROR: failed serializing krb5 context for kernel\n");
2667 - if (buf->value) free(buf->value);
2671 + buf->value = NULL;