The complete set of CITI nfs-utils patches rolled into one patch. Changes since CITI-NFS4_ALL-22 * Fix from kwc for gssd hang that would happen after a downcall failed (e.g. because a user without credentials attempted a filesystem operation) * minor error reporting fix --- nfs-utils-1.0.6-bfields/ChangeLog | 77 nfs-utils-1.0.6-bfields/config.mk.in | 4 nfs-utils-1.0.6-bfields/configure | 683 +++++++ nfs-utils-1.0.6-bfields/configure.in | 125 + nfs-utils-1.0.6-bfields/debian/changelog | 50 nfs-utils-1.0.6-bfields/debian/control | 2 nfs-utils-1.0.6-bfields/debian/etc.exports | 2 nfs-utils-1.0.6-bfields/debian/idmapd.conf | 10 nfs-utils-1.0.6-bfields/debian/nfs-common.conffiles | 1 nfs-utils-1.0.6-bfields/debian/nfs-common.default | 8 nfs-utils-1.0.6-bfields/debian/nfs-common.files | 2 nfs-utils-1.0.6-bfields/debian/nfs-common.init | 85 nfs-utils-1.0.6-bfields/debian/nfs-common.install | 1 nfs-utils-1.0.6-bfields/debian/nfs-common.postinst | 7 nfs-utils-1.0.6-bfields/debian/nfs-common.postrm | 4 nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.NEWS | 8 nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.conffiles | 1 nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.init | 39 nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.postinst | 34 nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.postrm | 4 nfs-utils-1.0.6-bfields/debian/rules | 11 nfs-utils-1.0.6-bfields/support/export/client.c | 4 nfs-utils-1.0.6-bfields/support/export/nfsctl.c | 2 nfs-utils-1.0.6-bfields/support/gssapi/Makefile | 24 nfs-utils-1.0.6-bfields/support/gssapi/SAMPLE_gssapi_mech.conf | 19 nfs-utils-1.0.6-bfields/support/gssapi/g_accept_sec_context.c | 213 ++ nfs-utils-1.0.6-bfields/support/gssapi/g_acquire_cred.c | 539 ++++++ nfs-utils-1.0.6-bfields/support/gssapi/g_compare_name.c | 165 + nfs-utils-1.0.6-bfields/support/gssapi/g_context_time.c | 75 nfs-utils-1.0.6-bfields/support/gssapi/g_delete_sec_context.c | 88 nfs-utils-1.0.6-bfields/support/gssapi/g_dsp_name.c | 96 + nfs-utils-1.0.6-bfields/support/gssapi/g_dsp_status.c | 86 nfs-utils-1.0.6-bfields/support/gssapi/g_dup_name.c | 162 + nfs-utils-1.0.6-bfields/support/gssapi/g_exp_sec_context.c | 108 + nfs-utils-1.0.6-bfields/support/gssapi/g_glue.c | 344 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_imp_name.c | 161 + nfs-utils-1.0.6-bfields/support/gssapi/g_imp_sec_context.c | 128 + nfs-utils-1.0.6-bfields/support/gssapi/g_indicate_mechs.c | 90 + nfs-utils-1.0.6-bfields/support/gssapi/g_init_sec_context.c | 194 ++ nfs-utils-1.0.6-bfields/support/gssapi/g_initialize.c | 380 ++++ nfs-utils-1.0.6-bfields/support/gssapi/g_inq_context.c | 143 + nfs-utils-1.0.6-bfields/support/gssapi/g_inq_cred.c | 199 ++ nfs-utils-1.0.6-bfields/support/gssapi/g_inq_names.c | 69 nfs-utils-1.0.6-bfields/support/gssapi/g_mechname.c | 116 + nfs-utils-1.0.6-bfields/support/gssapi/g_mit_krb5_mech.c | 297 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_oid_ops.c | 121 + nfs-utils-1.0.6-bfields/support/gssapi/g_process_context.c | 75 nfs-utils-1.0.6-bfields/support/gssapi/g_rel_buffer.c | 58 nfs-utils-1.0.6-bfields/support/gssapi/g_rel_cred.c | 104 + nfs-utils-1.0.6-bfields/support/gssapi/g_rel_name.c | 92 + nfs-utils-1.0.6-bfields/support/gssapi/g_rel_oid_set.c | 63 nfs-utils-1.0.6-bfields/support/gssapi/g_seal.c | 155 + nfs-utils-1.0.6-bfields/support/gssapi/g_set_allowable_enctypes.c | 81 nfs-utils-1.0.6-bfields/support/gssapi/g_sign.c | 99 + nfs-utils-1.0.6-bfields/support/gssapi/g_unseal.c | 105 + nfs-utils-1.0.6-bfields/support/gssapi/g_verify.c | 137 + nfs-utils-1.0.6-bfields/support/gssapi/gen_oids.c | 80 nfs-utils-1.0.6-bfields/support/gssapi/gssd_pname_to_uid.c | 71 nfs-utils-1.0.6-bfields/support/gssapi/mechglue.h | 46 nfs-utils-1.0.6-bfields/support/gssapi/mglueP.h | 503 +++++ nfs-utils-1.0.6-bfields/support/gssapi/oid_ops.c | 449 +++++ nfs-utils-1.0.6-bfields/support/include/config.h.in | 20 nfs-utils-1.0.6-bfields/support/include/exportfs.h | 1 nfs-utils-1.0.6-bfields/support/include/gssapi/gssapi.h | 846 +++++++++ nfs-utils-1.0.6-bfields/support/include/ha-callout.h | 52 nfs-utils-1.0.6-bfields/support/include/nfslib.h | 3 nfs-utils-1.0.6-bfields/support/lib/Makefile | 2 nfs-utils-1.0.6-bfields/support/nfs/cacheio.c | 8 nfs-utils-1.0.6-bfields/support/rpc/include/rpc/auth.h | 216 ++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/auth_gss.h | 122 + nfs-utils-1.0.6-bfields/support/rpc/include/rpc/auth_unix.h | 84 nfs-utils-1.0.6-bfields/support/rpc/include/rpc/clnt.h | 373 ++++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/pmap_clnt.h | 87 nfs-utils-1.0.6-bfields/support/rpc/include/rpc/pmap_prot.h | 106 + nfs-utils-1.0.6-bfields/support/rpc/include/rpc/pmap_rmt.h | 65 nfs-utils-1.0.6-bfields/support/rpc/include/rpc/rpc.h | 109 + nfs-utils-1.0.6-bfields/support/rpc/include/rpc/rpc_des.h | 133 + nfs-utils-1.0.6-bfields/support/rpc/include/rpc/rpc_msg.h | 197 ++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/svc.h | 334 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/svc_auth.h | 81 nfs-utils-1.0.6-bfields/support/rpc/include/rpc/types.h | 66 nfs-utils-1.0.6-bfields/support/rpc/include/rpc/xdr.h | 310 +++ nfs-utils-1.0.6-bfields/tools/rpcdebug/Makefile | 2 nfs-utils-1.0.6-bfields/tools/rpcdebug/rpcdebug.c | 150 - nfs-utils-1.0.6-bfields/utils/Makefile.in | 2 nfs-utils-1.0.6-bfields/utils/exportfs/exportfs.c | 69 nfs-utils-1.0.6-bfields/utils/exportfs/exports.man | 27 nfs-utils-1.0.6-bfields/utils/gssd/Makefile | 15 nfs-utils-1.0.6-bfields/utils/gssd/context.c | 467 +++++ nfs-utils-1.0.6-bfields/utils/gssd/context.h | 38 nfs-utils-1.0.6-bfields/utils/gssd/context_heimdal.c | 256 ++ nfs-utils-1.0.6-bfields/utils/gssd/err_util.c | 92 + nfs-utils-1.0.6-bfields/utils/gssd/err_util.h | 37 nfs-utils-1.0.6-bfields/utils/gssd/gss_clnt_send_err.c | 104 + nfs-utils-1.0.6-bfields/utils/gssd/gss_destroy_creds | 11 nfs-utils-1.0.6-bfields/utils/gssd/gss_oids.c | 39 nfs-utils-1.0.6-bfields/utils/gssd/gss_oids.h | 46 nfs-utils-1.0.6-bfields/utils/gssd/gss_util.c | 212 ++ nfs-utils-1.0.6-bfields/utils/gssd/gss_util.h | 44 nfs-utils-1.0.6-bfields/utils/gssd/gssd.c | 134 + nfs-utils-1.0.6-bfields/utils/gssd/gssd.h | 89 + nfs-utils-1.0.6-bfields/utils/gssd/gssd.man | 63 nfs-utils-1.0.6-bfields/utils/gssd/gssd_main_loop.c | 144 + nfs-utils-1.0.6-bfields/utils/gssd/gssd_proc.c | 670 +++++++ nfs-utils-1.0.6-bfields/utils/gssd/krb5_util.c | 809 +++++++++ nfs-utils-1.0.6-bfields/utils/gssd/krb5_util.h | 30 nfs-utils-1.0.6-bfields/utils/gssd/write_bytes.h | 139 + nfs-utils-1.0.6-bfields/utils/gssdestroycreds/Makefile | 14 nfs-utils-1.0.6-bfields/utils/idmapd/Makefile | 12 nfs-utils-1.0.6-bfields/utils/idmapd/atomicio.c | 63 nfs-utils-1.0.6-bfields/utils/idmapd/cfg.c | 889 ++++++++++ nfs-utils-1.0.6-bfields/utils/idmapd/cfg.h | 67 nfs-utils-1.0.6-bfields/utils/idmapd/idmapd.c | 884 +++++++++ nfs-utils-1.0.6-bfields/utils/idmapd/idmapd.conf | 10 nfs-utils-1.0.6-bfields/utils/idmapd/idmapd.conf.man | 74 nfs-utils-1.0.6-bfields/utils/idmapd/idmapd.man | 94 + nfs-utils-1.0.6-bfields/utils/idmapd/nfs_idmap.h | 71 nfs-utils-1.0.6-bfields/utils/idmapd/queue.h | 499 +++++ nfs-utils-1.0.6-bfields/utils/idmapd/setproctitle.c | 110 + nfs-utils-1.0.6-bfields/utils/idmapd/strlcat.c | 77 nfs-utils-1.0.6-bfields/utils/idmapd/strlcpy.c | 73 nfs-utils-1.0.6-bfields/utils/mountd/auth.c | 1 nfs-utils-1.0.6-bfields/utils/mountd/cache.c | 7 nfs-utils-1.0.6-bfields/utils/mountd/mountd.c | 22 nfs-utils-1.0.6-bfields/utils/mountd/mountd.man | 24 nfs-utils-1.0.6-bfields/utils/mountd/rmtab.c | 10 nfs-utils-1.0.6-bfields/utils/statd/monitor.c | 53 nfs-utils-1.0.6-bfields/utils/statd/rmtcall.c | 3 nfs-utils-1.0.6-bfields/utils/statd/statd.c | 25 nfs-utils-1.0.6-bfields/utils/statd/statd.h | 2 nfs-utils-1.0.6-bfields/utils/statd/statd.man | 29 nfs-utils-1.0.6-bfields/utils/statd/svc_run.c | 5 nfs-utils-1.0.6-bfields/utils/svcgssd/Makefile | 22 nfs-utils-1.0.6-bfields/utils/svcgssd/cacheio.c | 289 +++ nfs-utils-1.0.6-bfields/utils/svcgssd/cacheio.h | 48 nfs-utils-1.0.6-bfields/utils/svcgssd/svcgssd.c | 209 ++ nfs-utils-1.0.6-bfields/utils/svcgssd/svcgssd.h | 43 nfs-utils-1.0.6-bfields/utils/svcgssd/svcgssd.man | 41 nfs-utils-1.0.6-bfields/utils/svcgssd/svcgssd_main_loop.c | 86 nfs-utils-1.0.6-bfields/utils/svcgssd/svcgssd_mech2file.c | 77 nfs-utils-1.0.6-bfields/utils/svcgssd/svcgssd_proc.c | 339 +++ nfs-utils-1.0.6/debian/nfs-common.config | 10 nfs-utils-1.0.6/debian/nfs-common.templates | 5 nfs-utils-1.0.6/debian/nfs-kernel-server.config | 15 nfs-utils-1.0.6/debian/nfs-kernel-server.templates | 17 nfs-utils-1.0.6/etc/nodist/nfs-client | 74 nfs-utils-1.0.6/etc/nodist/nfs-functions | 104 - nfs-utils-1.0.6/etc/nodist/nfs-server | 129 - nfs-utils-1.0.6/etc/redhat/nfs | 31 nfs-utils-1.0.6/etc/redhat/nfs.init | 182 -- nfs-utils-1.0.6/etc/redhat/nfslock.init | 90 - nfs-utils-1.0.6/nfs-utils.spec | 110 - nfs-utils-1.0.6/nfs-utils.spec.in | 110 - 153 files changed, 18073 insertions(+), 1079 deletions(-) diff -puN ChangeLog~CITI_NFS4_ALL ChangeLog --- nfs-utils-1.0.6/ChangeLog~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/ChangeLog 2004-10-27 18:02:49.000000000 -0400 @@ -1,3 +1,78 @@ +2004-10-19 "J. Bruce Fields" + + * support/gssapi/* support/rpc/* utils/gssd/* utils/svcgssd/* etc + initial support for GSSAPI authentication + +2004-09-15 Neil Brown + + * utils/statd/monitor.c(sm_unmon_1_svc): is RESTRICTED_STATD, then + check IP address and force my_name to 127.0.0.1 to match + what happens in sm_mon_1_svc. This avoid spurious "erroneous + SM_UNMON" messages. + * utils/statd.monitor.c(sm_unmon_all_1_svc): likewise + +2004-09-15 "J. Bruce Fields" + + * Assorted changes to support "gss/*" style authentication + * utils/idmapd: new idmapd daemon for nfsv4 username lookup + +2004-09-06 Trond Myklebust + Neil Brown + + * utils/mountd/auth.c(auth_authenticate_internal): fix + uninitialsed variable problem (causes bad error messages). + +2004-09-06 Paul Clements + Neil Brown + + * utils/mountd/mountd.c(main): support --ha-callout (-H) for + specifying a callout program + * utils/mountd/rmtab.c: Call ha_callout on mount/unmount + * utils/statd/monitor.c: Call ha_callout on add/del client + * utils/statd/rmtcall.c: as above + * utils/statd/statd.c: handle --ha-callout (-H) + * utils/statd/svc_run.c: call notify_hosts is we have received a + sighup + * support/include/ha-callout.h: define ha_callout function + + +2004-08-31 NeilBrown + * utils/mountd/cache.c(cache_process_req): clear fd after + processing so as not to confused libc/sunrpc into thinking + it need to do something with that fd. + +2004-08-31 NeilBrown + + * debian/nfs-kernel-server.init(start,stop) mount the nfsd + filesystem, if available, before starting nfs services, and + unmount it afterwards. + * etc/nodist/nfs-server: ditto + * etc/redhat/nfs.init: likewise + * etc/redhat/nfs: add "MOUNT_NFSD" flag to control above. + +2004-06-08 NeilBrown + + * utils/exportfs/exportfs.c: Don't rmtab_read if new_cache, it + isn't necessary. + * support/nfs/cacheio.c(cache_flush): Change order in which caches + are flushed so that dependancies don't keep things in the cache + too long. + +2004-03-18 Chip Salzenberg + + * debian/changelog: Version 1.0.6-2. + +2004-02-24 NeilBrown + from "J. Bruce Fields" + + * utils/mountd/cache.c: call auth_reload to make sure auth data is + current before responding to kernel upcall. + +2004-02-24 NeilBrown + Based on patch from Greg Banks + + * utils/exportfs/exports.man: Document fsid= option. + 2003-09-15 NeilBrown Release 1.0.6 @@ -8,7 +83,7 @@ utils/statd/Makefile: add "predep" rule so that "make dep" works. * Makefile: allow a simple "make" to run ./configure and "make dep" if needed. - * configure.in, nfs-utils.spec: Update version to 1.0.4 + * configure.in, nfs-utils.spec: Update version to 1.0.6 * run autoconf 2003-09-12 Chip Salzenberg diff -puN config.mk.in~CITI_NFS4_ALL config.mk.in --- nfs-utils-1.0.6/config.mk.in~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/config.mk.in 2004-10-27 18:02:49.000000000 -0400 @@ -33,6 +33,9 @@ MANGROUP = root LIBBSD = @LIBBSD@ LIBNSL = @LIBNSL@ LIBWRAP = @LIBWRAP@ +KRBLIB = @KRBLIB@ +KRBDIR = @KRBDIR@ +KRB5_VERSION = @K5VERS@ ################# END OF USER SERVICEABLE PARTS ################## ALLTARGETS = all clean distclean install installman \ @@ -58,6 +61,7 @@ INSTALL = install MAN2PS = groff -Tps -man AFLAGS = -I$(TOP)support/include \ + -I$(KRBDIR)/include \ -Wall $(ARCHFLAGS) -pipe ifdef KERNEL_INCDIR AFLAGS += -I$(KERNEL_INCDIR) diff -puN configure~CITI_NFS4_ALL configure --- nfs-utils-1.0.6/configure~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/configure 2004-10-27 18:02:50.000000000 -0400 @@ -21,11 +21,17 @@ ac_help="$ac_help ac_help="$ac_help --enable-nfsv3 enable support for NFSv3" ac_help="$ac_help + --enable-nfsv4 enable support for NFSv4" +ac_help="$ac_help + --enable-gss enable support for rpcsec_gss" +ac_help="$ac_help --enable-kprefix install progs as rpc.knfsd etc" ac_help="$ac_help --enable-secure-statd Only lockd can use statd (security)" ac_help="$ac_help --enable-rquotad enable rquotad" +ac_help="$ac_help + --with-krb5=DIR use Kerberos v5 installation in DIR" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -590,6 +596,49 @@ EOF enable_nfsv3= fi +# Check whether --enable-nfsv4 or --disable-nfsv4 was given. +if test "${enable_nfsv4+set}" = set; then + enableval="$enable_nfsv4" + enable_nfsv4=$enableval +else + enable_nfsv4=yes +fi + + if test "$enable_nfsv4" = yes; then + cat >> confdefs.h <<\EOF +#define NFS4_SUPPORTED 1 +EOF + + IDMAPD=idmapd + else + enable_nfsv4= + IDMAPD= + fi + + +# Check whether --enable-gss or --disable-gss was given. +if test "${enable_gss+set}" = set; then + enableval="$enable_gss" + enable_gss=$enableval +else + enable_gss=yes +fi + + if test "$enable_gss" = yes; then + cat >> confdefs.h <<\EOF +#define GSS_SUPPORTED 1 +EOF + + GSSD=gssd + SVCGSSD=svcgssd + else + enable_gss= + GSSD= + SVCGSSD= + fi + + + # Check whether --enable-kprefix or --disable-kprefix was given. if test "${enable_kprefix+set}" = set; then enableval="$enable_kprefix" @@ -633,7 +682,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:637: checking for $ac_word" >&5 +echo "configure:686: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -663,7 +712,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:667: checking for $ac_word" >&5 +echo "configure:716: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -714,7 +763,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:718: checking for $ac_word" >&5 +echo "configure:767: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -746,7 +795,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:750: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:799: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -757,12 +806,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 761 "configure" +#line 810 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:815: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -788,12 +837,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:792: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:841: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:797: checking whether we are using GNU C" >&5 +echo "configure:846: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -802,7 +851,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:806: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:855: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -821,7 +870,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:825: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:874: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -853,7 +902,7 @@ else fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:857: checking how to run the C preprocessor" >&5 +echo "configure:906: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -868,13 +917,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:878: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:927: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -885,13 +934,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:944: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -902,13 +951,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:912: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:961: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -963,7 +1012,7 @@ ac_configure=$ac_aux_dir/configure # Thi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:967: checking for a BSD compatible install" >&5 +echo "configure:1016: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1026,7 +1075,7 @@ else { echo "configure: error: can not r fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:1030: checking host system type" >&5 +echo "configure:1079: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -1047,7 +1096,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)- echo "$ac_t""$host" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1051: checking build system type" >&5 +echo "configure:1100: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -1073,7 +1122,7 @@ fi # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1077: checking for $ac_word" >&5 +echo "configure:1126: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1105,7 +1154,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1109: checking for $ac_word" >&5 +echo "configure:1158: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1140,7 +1189,7 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1144: checking for $ac_word" >&5 +echo "configure:1193: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1172,7 +1221,7 @@ fi # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. set dummy ${ac_tool_prefix}ld; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1176: checking for $ac_word" >&5 +echo "configure:1225: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1203,12 +1252,12 @@ fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1207: checking for ANSI C header files" >&5 +echo "configure:1256: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1216,7 +1265,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1220: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1233,7 +1282,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1251,7 +1300,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1272,7 +1321,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1283,7 +1332,7 @@ if (XOR (islower (i), ISLOWER (i)) || to exit (0); } EOF -if { (eval echo configure:1287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1307,12 +1356,12 @@ EOF fi echo $ac_n "checking for GNU libc2""... $ac_c" 1>&6 -echo "configure:1311: checking for GNU libc2" >&5 +echo "configure:1360: checking for GNU libc2" >&5 if eval "test \"`echo '$''{'knfsd_cv_glibc2'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -1321,7 +1370,7 @@ else #endif EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1325: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1374: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1344,7 +1393,7 @@ fi echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 -echo "configure:1348: checking for main in -lsocket" >&5 +echo "configure:1397: checking for main in -lsocket" >&5 ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1352,14 +1401,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1380,7 +1429,7 @@ else fi echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6 -echo "configure:1384: checking for main in -lnsl" >&5 +echo "configure:1433: checking for main in -lnsl" >&5 ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1388,14 +1437,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1416,7 +1465,7 @@ else fi echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:1420: checking for crypt in -lcrypt" >&5 +echo "configure:1469: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1424,7 +1473,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1455,9 +1504,185 @@ else echo "$ac_t""no" 1>&6 fi +if test "$enable_nfsv4" = yes; then + echo $ac_n "checking for event_dispatch in -levent""... $ac_c" 1>&6 +echo "configure:1510: checking for event_dispatch in -levent" >&5 +ac_lib_var=`echo event'_'event_dispatch | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-levent $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo event | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + echo $ac_n "checking for nfs4_init_name_mapping in -lnfsidmap""... $ac_c" 1>&6 +echo "configure:1557: checking for nfs4_init_name_mapping in -lnfsidmap" >&5 +ac_lib_var=`echo nfsidmap'_'nfs4_init_name_mapping | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lnfsidmap $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo nfsidmap | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + for ac_hdr in event.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1607: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1617: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + + for ac_hdr in nfsidmap.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:1647: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1657: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + +fi if test "$knfsd_cv_glibc2" = no; then echo $ac_n "checking for daemon in -lbsd""... $ac_c" 1>&6 -echo "configure:1461: checking for daemon in -lbsd" >&5 +echo "configure:1686: checking for daemon in -lbsd" >&5 ac_lib_var=`echo bsd'_'daemon | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1465,7 +1690,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1705: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1503,14 +1728,14 @@ fi echo $ac_n "checking for the tcp wrapper library""... $ac_c" 1>&6 -echo "configure:1507: checking for the tcp wrapper library" >&5 +echo "configure:1732: checking for the tcp wrapper library" >&5 if eval "test \"`echo '$''{'knfsd_cv_tcp_wrapper'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else old_LIBS="$LIBS" LIBS="$LIBS -lwrap $LIBNSL" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* knfsd_cv_tcp_wrapper=yes else @@ -1541,16 +1766,358 @@ fi +if test "$enable_gss" = yes; then + echo $ac_n "checking for Kerberos v5""... $ac_c" 1>&6 +echo "configure:1772: checking for Kerberos v5" >&5 + # Check whether --with-krb5 or --without-krb5 was given. +if test "${with_krb5+set}" = set; then + withval="$with_krb5" + case "$withval" in + yes|no) + krb5_with="" + ;; + *) + krb5_with="$withval" + ;; + esac + +fi + + + for dir in $krb5_with /usr/kerberos /usr/local /usr/local/krb5 /usr/krb5 \ + /usr/heimdal /usr/local/heimdal /usr/athena /usr ; do + K5CONFIG="" + if test -f $dir/bin/krb5-config; then + K5CONFIG=$dir/bin/krb5-config + elif test -f "/usr/kerberos/bin/krb5-config"; then + K5CONFIG="/usr/kerberos/bin/krb5-config" + fi + if test "$K5CONFIG" != ""; then + if test -f $dir/include/gssapi/gssapi_krb5.h -a \ + \( -f $dir/lib/libgssapi_krb5.a -o \ + -f $dir/lib/libgssapi_krb5.so \) ; then + cat >> confdefs.h <<\EOF +#define HAVE_KRB5 1 +EOF + + KRBDIR="$dir" + K5VERS=`$K5CONFIG --version | awk '{split($4,v,"."); print v[1]v[2]v[3] }'` + cat >> confdefs.h <> confdefs.h <<\EOF +#define USE_PRIVATE_KRB5_FUNCTIONS 1 +EOF + + fi + echo $ac_n "checking for gss_krb5_export_lucid_sec_context in -lgssapi_krb5""... $ac_c" 1>&6 +echo "configure:1818: checking for gss_krb5_export_lucid_sec_context in -lgssapi_krb5" >&5 +ac_lib_var=`echo gssapi_krb5'_'gss_krb5_export_lucid_sec_context | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi_krb5 $KRBLIB $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LUCID_CONTEXT_SUPPORT 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for gss_krb5_set_allowable_enctypes in -lgssapi_krb5""... $ac_c" 1>&6 +echo "configure:1861: checking for gss_krb5_set_allowable_enctypes in -lgssapi_krb5" >&5 +ac_lib_var=`echo gssapi_krb5'_'gss_krb5_set_allowable_enctypes | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi_krb5 $KRBLIB $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SET_ALLOWABLE_ENCTYPES 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for gss_krb5_ccache_name in -lgssapi_krb5""... $ac_c" 1>&6 +echo "configure:1904: checking for gss_krb5_ccache_name in -lgssapi_krb5" >&5 +ac_lib_var=`echo gssapi_krb5'_'gss_krb5_ccache_name | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi_krb5 $KRBLIB $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GSS_KRB5_CCACHE_NAME 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + break + elif test \( -f $dir/include/heim_err.h -o\ + -f $dir/include/heimdal/heim_err.h \) -a \ + -f $dir/lib/libroken.a; then + cat >> confdefs.h <<\EOF +#define HAVE_HEIMDAL 1 +EOF + + KRBDIR="$dir" + K5VERS=`$K5CONFIG --version | head -1 | awk '{split($2,v,"."); print v[1]v[2]v[3] }'` + cat >> confdefs.h <&6 +echo "configure:1962: checking for gss_krb5_export_lucid_sec_context in -lgssapi" >&5 +ac_lib_var=`echo gssapi'_'gss_krb5_export_lucid_sec_context | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi $KRBLIB $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_LUCID_CONTEXT_SUPPORT 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for gss_krb5_set_allowable_enctypes in -lgssapi""... $ac_c" 1>&6 +echo "configure:2005: checking for gss_krb5_set_allowable_enctypes in -lgssapi" >&5 +ac_lib_var=`echo gssapi'_'gss_krb5_set_allowable_enctypes | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi $KRBLIB $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SET_ALLOWABLE_ENCTYPES 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + echo $ac_n "checking for gss_krb5_ccache_name in -lgssapi""... $ac_c" 1>&6 +echo "configure:2048: checking for gss_krb5_ccache_name in -lgssapi" >&5 +ac_lib_var=`echo gssapi'_'gss_krb5_ccache_name | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lgssapi $KRBLIB $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GSS_KRB5_CCACHE_NAME 1 +EOF + +else + echo "$ac_t""no" 1>&6 +fi + + break + fi + CFLAGS=$CFLAGS `K5CONFIG --cflags` + fi + done + if test "x$KRBDIR" = "x"; then + if test "x$krb5_with" = "x"; then + { echo "configure: error: Kerberos v5 with GSS support not found" 1>&2; exit 1; } + else + { echo "configure: error: Kerberos v5 with GSS support not found at $krb5_with" 1>&2; exit 1; } + fi + fi + echo "$ac_t""$KRBDIR" 1>&6 + if test "x$krb5_with" != "x" -a "$krb5_with" != "$KRBDIR"; then + echo "configure: warning: Using $KRBDIR instead of requested value of $krb5_with for Kerberos!" 1>&2 + fi + + + + +fi + for ac_func in innetgr do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1549: checking for $ac_func" >&5 +echo "configure:2116: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1707,7 +2274,7 @@ done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" -trap 'rm -fr `echo "config.mk nfs-utils.spec utils/Makefile support/include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +trap 'rm -fr `echo "config.mk utils/Makefile support/include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then diff -puN configure.in~CITI_NFS4_ALL configure.in --- nfs-utils-1.0.6/configure.in~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/configure.in 2004-10-27 18:02:50.000000000 -0400 @@ -39,6 +39,35 @@ AC_ARG_ENABLE(nfsv3, enable_nfsv3= fi AC_SUBST(enable_nfsv3) +AC_ARG_ENABLE(nfsv4, + [ --enable-nfsv4 enable support for NFSv4], + enable_nfsv4=$enableval, + enable_nfsv4=yes) + if test "$enable_nfsv4" = yes; then + AC_DEFINE(NFS4_SUPPORTED) + IDMAPD=idmapd + else + enable_nfsv4= + IDMAPD= + fi + AC_SUBST(IDMAPD) + AC_SUBST(enable_nfsv4) +AC_ARG_ENABLE(gss, + [ --enable-gss enable support for rpcsec_gss], + enable_gss=$enableval, + enable_gss=yes) + if test "$enable_gss" = yes; then + AC_DEFINE(GSS_SUPPORTED) + GSSD=gssd + SVCGSSD=svcgssd + else + enable_gss= + GSSD= + SVCGSSD= + fi + AC_SUBST(GSSD) + AC_SUBST(SVCGSSD) + AC_SUBST(enable_gss) AC_ARG_ENABLE(kprefix, [ --enable-kprefix install progs as rpc.knfsd etc], test "$enableval" = "yes" && kprefix=k, @@ -87,6 +116,12 @@ dnl ************************************ AC_CHECK_LIB(socket, main, [LIBSOCKET="-lnsl"]) AC_CHECK_LIB(nsl, main, [LIBNSL="-lnsl"]) AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"]) +if test "$enable_nfsv4" = yes; then + AC_CHECK_LIB(event, event_dispatch) + AC_CHECK_LIB(nfsidmap, nfs4_init_name_mapping) + AC_CHECK_HEADERS(event.h) + AC_CHECK_HEADERS(nfsidmap.h) +fi if test "$knfsd_cv_glibc2" = no; then AC_CHECK_LIB(bsd, daemon, [LIBBSD="-lbsd"]) fi @@ -98,6 +133,94 @@ AC_SUBST(LIBBSD) AC_TCP_WRAPPER AC_SUBST(LIBWRAP) +if test "$enable_gss" = yes; then + dnl Checks for Kerberos + dnl NOTE: while we intend to do generic gss-api, currently we + dnl have a requirement to get an initial Kerberos machine + dnl credential. Thus, the requirement for Kerberos. + dnl The Kerberos gssapi library will be dynamically loaded? + AC_MSG_CHECKING(for Kerberos v5) + AC_ARG_WITH(krb5, + [ --with-krb5=DIR use Kerberos v5 installation in DIR], + [ case "$withval" in + yes|no) + krb5_with="" + ;; + *) + krb5_with="$withval" + ;; + esac ] + ) + + for dir in $krb5_with /usr/kerberos /usr/local /usr/local/krb5 /usr/krb5 \ + /usr/heimdal /usr/local/heimdal /usr/athena /usr ; do + dnl This ugly hack brought on by the split installation of + dnl MIT Kerberos on Fedora Core 1 + K5CONFIG="" + if test -f $dir/bin/krb5-config; then + K5CONFIG=$dir/bin/krb5-config + elif test -f "/usr/kerberos/bin/krb5-config"; then + K5CONFIG="/usr/kerberos/bin/krb5-config" + fi + if test "$K5CONFIG" != ""; then + if test -f $dir/include/gssapi/gssapi_krb5.h -a \ + \( -f $dir/lib/libgssapi_krb5.a -o \ + -f $dir/lib/libgssapi_krb5.so \) ; then + AC_DEFINE(HAVE_KRB5) + KRBDIR="$dir" + K5VERS=`$K5CONFIG --version | awk '{split($4,v,"."); print v[[1]]v[[2]]v[[3]] }'` + AC_DEFINE_UNQUOTED(KRB5_VERSION,$K5VERS) + KRBLIB=`$K5CONFIG --libs gssapi` + if test $K5VERS -le 131; then + AC_DEFINE(USE_PRIVATE_KRB5_FUNCTIONS) + fi + AC_CHECK_LIB(gssapi_krb5, gss_krb5_export_lucid_sec_context, + AC_DEFINE(HAVE_LUCID_CONTEXT_SUPPORT),,$KRBLIB) + AC_CHECK_LIB(gssapi_krb5, gss_krb5_set_allowable_enctypes, + AC_DEFINE(HAVE_SET_ALLOWABLE_ENCTYPES),,$KRBLIB) + AC_CHECK_LIB(gssapi_krb5, gss_krb5_ccache_name, + AC_DEFINE(HAVE_GSS_KRB5_CCACHE_NAME),,$KRBLIB) + break + dnl The following ugly hack brought on by the split installation + dnl of Heimdal Kerberos on SuSe + elif test \( -f $dir/include/heim_err.h -o\ + -f $dir/include/heimdal/heim_err.h \) -a \ + -f $dir/lib/libroken.a; then + AC_DEFINE(HAVE_HEIMDAL) + KRBDIR="$dir" + K5VERS=`$K5CONFIG --version | head -1 | awk '{split($2,v,"."); print v[[1]]v[[2]]v[[3]] }'` + AC_DEFINE_UNQUOTED(KRB5_VERSION,$K5VERS) + KRBLIB=`$K5CONFIG --libs gssapi` + AC_CHECK_LIB(gssapi, gss_krb5_export_lucid_sec_context, + AC_DEFINE(HAVE_LUCID_CONTEXT_SUPPORT),,$KRBLIB) + AC_CHECK_LIB(gssapi, gss_krb5_set_allowable_enctypes, + AC_DEFINE(HAVE_SET_ALLOWABLE_ENCTYPES),,$KRBLIB) + AC_CHECK_LIB(gssapi, gss_krb5_ccache_name, + AC_DEFINE(HAVE_GSS_KRB5_CCACHE_NAME),,$KRBLIB) + break + fi + CFLAGS=$CFLAGS `K5CONFIG --cflags` + fi + done + dnl We didn't find a usable Kerberos environment + if test "x$KRBDIR" = "x"; then + if test "x$krb5_with" = "x"; then + AC_MSG_ERROR(Kerberos v5 with GSS support not found) + else + AC_MSG_ERROR(Kerberos v5 with GSS support not found at $krb5_with) + fi + fi + AC_MSG_RESULT($KRBDIR) + dnl If they specified a directory and it didn't work, give them a warning + if test "x$krb5_with" != "x" -a "$krb5_with" != "$KRBDIR"; then + AC_MSG_WARN(Using $KRBDIR instead of requested value of $krb5_with for Kerberos!) + fi + + AC_SUBST([KRBDIR]) + AC_SUBST([KRBLIB]) + AC_SUBST([K5VERS]) +fi + dnl ************************************************************* dnl Check for headers dnl ************************************************************* @@ -116,4 +239,4 @@ AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$state AC_SUBST(LDFLAGS) AC_SUBST(CXXFLAGS) AC_SUBST(CFLAGS) -AC_OUTPUT(config.mk nfs-utils.spec utils/Makefile) +AC_OUTPUT(config.mk utils/Makefile) diff -puN debian/changelog~CITI_NFS4_ALL debian/changelog --- nfs-utils-1.0.6/debian/changelog~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/changelog 2004-10-27 18:02:50.000000000 -0400 @@ -1,3 +1,53 @@ +nfs-utils (1:1.0.6.nfsv4-5) unstable; urgency=low + + * Fix gssd hang that would happen after a downcall failure (e.g. because + a user without credentials attempted a filesystem operation). + + -- J. Bruce Fields Wed, 27 Oct 2004 17:52:50 -0400 + +nfs-utils (1:1.0.6.nfsv4-4) unstable; urgency=low + + * Miscellaneous bugfixes + * Get default domain from libnfsidmapd instead of from config file + + -- J. Bruce Fields Sun, 17 Oct 2004 15:57:13 -0400 + +nfs-utils (1:1.0.6.nfsv4-3) unstable; urgency=low + * Change version to .nfsv4 + * Move idmapd and gssd into nfs-common + * Add build dependency on libevent-dev + + -- Trond Myklebust Wed, 1 Sep 2004 15:52:20 -0400 + +nfs-utils (2:1.0.6-3) unstable; urgency=low + + * Add nfsv4 and rpcsec_gss support. + + -- J. Bruce Fields Tue, 13 Jul 2004 17:33:25 -0500 + +nfs-utils (1:1.0.6-3) unstable; urgency=medium + + * Remove obsolete debconf-related files in debian/rules, because source + diffs don't implement removals. (closes: #239331) + + -- Chip Salzenberg Wed, 24 Mar 2004 18:09:21 -0500 + +nfs-utils (1:1.0.6-2) unstable; urgency=medium + + * Upstream CVS sync. + * Urgency "medium" to get debconf fix into testing. + * Remove debconf warning notes in favor of nfs-kernel-server.NEWS. + (closes: #228365) + * Make /etc/exports a conffile. (closes: #224557) + * Clean up /var/lib/nfs in postrm. + * Test kernel version in init script; all kernels from 2.4 forward + have a lockd thread, and don't need rpc.lockd. Probe older kernels + by checking for lockd-related symbols. When in doubt, go ahead and + run rpc.lockd; if it's not needed, it exits. (closes: #205867) + * Don't bother removing nfs-server's init links; it's long dead. + + -- Chip Salzenberg Thu, 18 Mar 2004 17:06:00 -0500 + nfs-utils (1:1.0.6-1) unstable; urgency=low * New upstream version: diff -puN debian/control~CITI_NFS4_ALL debian/control --- nfs-utils-1.0.6/debian/control~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/control 2004-10-27 18:02:49.000000000 -0400 @@ -2,7 +2,7 @@ Source: nfs-utils Priority: standard Section: net Maintainer: Chip Salzenberg -Build-Depends: debhelper (>= 4.1.16), libwrap0-dev +Build-Depends: debhelper (>= 4.1.16), libwrap0-dev, libevent-dev, libnfsidmap-dev, libkrb5-dev Standards-Version: 3.1.1.1 Package: nfs-kernel-server diff -puN /dev/null debian/etc.exports --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/etc.exports 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,2 @@ +# /etc/exports: the access control list for filesystems which may be exported +# to NFS clients. See exports(5). diff -L debian/gssapi_mech.conf -puN /dev/null /dev/null diff -puN /dev/null debian/idmapd.conf --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/idmapd.conf 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,10 @@ +[General] + +Verbosity = 0 +Pipefs-Directory = /var/lib/nfs/rpc_pipefs +Domain = localdomain + +[Mapping] + +Nobody-User = nobody +Nobody-Group = nogroup diff -puN debian/nfs-common.conffiles~CITI_NFS4_ALL debian/nfs-common.conffiles --- nfs-utils-1.0.6/debian/nfs-common.conffiles~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.conffiles 2004-10-27 18:02:50.000000000 -0400 @@ -1,2 +1,3 @@ /etc/default/nfs-common /etc/init.d/nfs-common +/etc/idmapd.conf diff -L debian/nfs-common.config -puN debian/nfs-common.config~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/debian/nfs-common.config +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,10 +0,0 @@ -#!/bin/sh -e - -. /usr/share/debconf/confmodule - -if egrep -q 'ALL|[0-9]\.' /etc/hosts.deny -then - db_input high nfs-common/tcpwrappers-statd || true -fi - -db_go diff -puN debian/nfs-common.default~CITI_NFS4_ALL debian/nfs-common.default --- nfs-utils-1.0.6/debian/nfs-common.default~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.default 2004-10-27 18:02:49.000000000 -0400 @@ -6,3 +6,11 @@ STATDOPTS= # Are you _sure_ that your kernel does or does not need a lockd daemon? # If so, set this variable to either "yes" or "no". NEED_LOCKD= + +# If you are not using NFSv4 and wish to disable the idmapd daemon +# then uncomment the following line +# NEED_IDMAPD=no + +# If you are not running NFS with RPCSEC_GSS security, and wish to +# disable the gssd client daemon then uncomment the following line +# NEED_GSSD=no diff -puN debian/nfs-common.files~CITI_NFS4_ALL debian/nfs-common.files --- nfs-utils-1.0.6/debian/nfs-common.files~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.files 2004-10-27 18:02:49.000000000 -0400 @@ -1,4 +1,6 @@ usr/sbin/nfsstat +usr/sbin/rpc.gssd +usr/sbin/rpc.idmapd usr/share/man/man8/*lockd* usr/share/man/man8/*statd* usr/share/man/man8/nfsstat* diff -puN debian/nfs-common.init~CITI_NFS4_ALL debian/nfs-common.init --- nfs-utils-1.0.6/debian/nfs-common.init~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.init 2004-10-27 18:02:49.000000000 -0400 @@ -18,26 +18,60 @@ DESC="NFS common utilities" DEFAULTFILE=/etc/default/nfs-common PREFIX= NEED_LOCKD= +NEED_IDMAPD=yes +IDMAPD_PIDFILE=/var/run/rpc.idmapd.pid +NEED_GSSD=yes +GSSD_PIDFILE=/var/run/rpc.gssd.pid +PIPEFS_MOUNTPOINT=/var/lib/nfs/rpc_pipefs +RPCGSSDOPTS= if [ -f $DEFAULTFILE ]; then . $DEFAULTFILE fi -# Determine whether lockd is required +# Determine whether lockd daemon is required. case "$NEED_LOCKD" in yes|no) ;; -*) # We must be conservative and run lockd, - # unless we can prove that it's not required. - NEED_LOCKD=yes - if test -f /proc/ksyms - then - grep -q lockdctl /proc/ksyms || NEED_LOCKD=no - fi +*) case `uname -r` in + '' | [01].* | 2.[0123].* ) + # Older kernels may or may not need a lockd daemon. + # We must assume they do, unless we can prove otherwise. + # (A false positive here results only in a harmless message.) + NEED_LOCKD=yes + if test -f /proc/ksyms + then + grep -q lockdctl /proc/ksyms || NEED_LOCKD=no + fi + ;; + + *) # Modern kernels (>= 2.4) start a lockd thread automatically. + NEED_LOCKD=no + ;; + esac ;; esac # Exit if required binaries are missing. [ -x $PREFIX/sbin/rpc.statd ] || exit 0 [ -x $PREFIX/sbin/rpc.lockd ] || [ "$NEED_LOCKD" = no ] || exit 0 +[ -x /usr/sbin/rpc.idmapd ] || [ "$NEED_IDMAPD" = no ] || exit 0 +[ -x /usr/sbin/rpc.gssd ] || [ "$NEED_GSSD" = no ] || exit 0 + +do_modprobe() { + modprobe -q $1 || true +} + +do_mount() { + if ! grep -E -qs "$1\$" /proc/filesystems + then + return 1 + fi + if ! mountpoint -q $2 + then + mount -t $1 $3 $1 $2 + return + fi + return 0 +} # See how we were called. case "$1" in @@ -53,11 +87,46 @@ case "$1" in start-stop-daemon --start --quiet \ --exec $PREFIX/sbin/rpc.lockd || true fi + if [ "$NEED_IDMAPD" = yes ] || [ "$NEED_GSSD" = yes ] + then + do_modprobe nfs + if do_mount rpc_pipefs $PIPEFS_MOUNTPOINT; + then + if [ "$NEED_IDMAPD" = yes ] + then + printf " idmapd" + start-stop-daemon --start --quiet \ + --make-pidfile --pidfile $IDMAPD_PIDFILE \ + --exec /usr/sbin/rpc.idmapd + fi + if [ "$NEED_GSSD" = yes ] + then + printf " gssd" + start-stop-daemon --start --quiet \ + --make-pidfile --pidfile $GSSD_PIDFILE \ + --exec /usr/sbin/rpc.gssd -- $RPCGSSDOPTS + fi + fi + fi echo "." ;; stop) printf "Stopping $DESC:" + if [ "$NEED_GSSD" = yes ] + then + printf " gssd" + start-stop-daemon --stop --oknodo --quiet \ + --name rpc.gssd --user 0 + rm -f $GSSD_PIDFILE + fi + if [ "$NEED_IDMAPD" = yes ] + then + printf " idmapd" + start-stop-daemon --stop --oknodo --quiet \ + --name rpc.idmapd --user 0 + rm -f $IDMAPD_PIDFILE + fi if [ "$NEED_LOCKD" = yes ] then printf " lockd" diff -puN /dev/null debian/nfs-common.install --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.install 2004-10-27 18:02:50.000000000 -0400 @@ -0,0 +1 @@ +debian/idmapd.conf etc diff -puN debian/nfs-common.postinst~CITI_NFS4_ALL debian/nfs-common.postinst --- nfs-utils-1.0.6/debian/nfs-common.postinst~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.postinst 2004-10-27 18:02:49.000000000 -0400 @@ -12,6 +12,13 @@ case "$1" in update-rc.d -f nfs-common remove >/dev/null 2>&1 || true fi update-rc.d nfs-common defaults 21 79 >/dev/null + + # Remove obsolete debconf questions + if [ -e /usr/share/debconf/confmodule ]; then + . /usr/share/debconf/confmodule + db_unregister nfs-common/tcpwrappers-statd || true + db_stop + fi ;; esac diff -puN debian/nfs-common.postrm~CITI_NFS4_ALL debian/nfs-common.postrm --- nfs-utils-1.0.6/debian/nfs-common.postrm~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-common.postrm 2004-10-27 18:02:49.000000000 -0400 @@ -5,5 +5,9 @@ case "$1" in purge) update-rc.d nfs-common remove >/dev/null + + rm -f /var/lib/nfs/state \ + /var/lib/nfs/sm/* \ + /var/lib/nfs/sm.bak/* ;; esac diff -L debian/nfs-common.templates -puN debian/nfs-common.templates~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/debian/nfs-common.templates +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,5 +0,0 @@ -Template: nfs-common/tcpwrappers-statd -Type: note -_Description: statd uses tcpwrappers - The statd daemon uses tcpwrappers to control access. To configure it, use - program name "statd" in /etc/hosts.allow and /etc/hosts.deny. diff -puN debian/nfs-kernel-server.conffiles~CITI_NFS4_ALL debian/nfs-kernel-server.conffiles --- nfs-utils-1.0.6/debian/nfs-kernel-server.conffiles~CITI_NFS4_ALL 2004-10-27 18:02:43.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.conffiles 2004-10-27 18:02:49.000000000 -0400 @@ -1,2 +1,3 @@ +/etc/exports /etc/default/nfs-kernel-server /etc/init.d/nfs-kernel-server diff -L debian/nfs-kernel-server.config -puN debian/nfs-kernel-server.config~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/debian/nfs-kernel-server.config +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,15 +0,0 @@ -#!/bin/sh -e - -. /usr/share/debconf/confmodule - -if grep -s '^/' /etc/exports | grep -vq sync -then - db_input high nfs-kernel-server/sync-default || true -fi - -if fgrep -q 'rpc' /etc/hosts.allow /etc/hosts.deny -then - db_input high nfs-kernel-server/tcpwrappers-mountd || true -fi - -db_go diff -puN debian/nfs-kernel-server.init~CITI_NFS4_ALL debian/nfs-kernel-server.init --- nfs-utils-1.0.6/debian/nfs-kernel-server.init~CITI_NFS4_ALL 2004-10-27 18:02:44.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.init 2004-10-27 18:02:49.000000000 -0400 @@ -20,26 +20,58 @@ PREFIX=/usr [ -x $PREFIX/sbin/rpc.nfsd ] || exit 0 [ -x $PREFIX/sbin/rpc.mountd ] || exit 0 [ -x $PREFIX/sbin/exportfs ] || exit 0 +[ -x $PREFIX/sbin/rpc.svcgssd ] || exit 0 # Read config DEFAULTFILE=/etc/default/nfs-kernel-server RPCNFSDCOUNT=8 RPCMOUNTDOPTS= +NEED_SVCGSSD=yes +RPCGSSDOPTS= +RPCSVCGSSDOPTS= +PROCNFSD_MOUNTPOINT=/proc/fs/nfsd if [ -f $DEFAULTFILE ]; then . $DEFAULTFILE fi +do_modprobe() { + modprobe -q $1 || true +} + +do_mount() { + if ! grep -E -qs "$1\$" /proc/filesystems + then + return 1 + fi + if ! mountpoint -q $2 + then + mount -t $1 $3 $1 $2 + return + fi + return 0 +} + # See how we were called. case "$1" in start) cd / # daemons should have root dir as cwd if grep -q '^/' /etc/exports then + do_modprobe nfsd + do_mount nfsd $PROCNFSD_MOUNTPOINT || NEED_SVCGSSD=no printf "Exporting directories for $DESC..." $PREFIX/sbin/exportfs -r echo "done." printf "Starting $DESC:" + if [ "$NEED_SVCGSSD" = yes ] + then + printf " svcgssd" + start-stop-daemon --start --quiet \ + --make-pidfile --pidfile /var/run/rpc.svcgssd.pid \ + --exec $PREFIX/sbin/rpc.svcgssd -- $RPCSVCGSSDOPTS + fi + printf " nfsd" start-stop-daemon --start --quiet \ --exec $PREFIX/sbin/rpc.nfsd -- $RPCNFSDCOUNT @@ -73,6 +105,13 @@ case "$1" in printf "Stopping $DESC: mountd" start-stop-daemon --stop --oknodo --quiet \ --name rpc.mountd --user 0 + if [ "$NEED_SVCGSSD" = yes ] + then + printf " svcgssd" + start-stop-daemon --stop --oknodo --quiet \ + --name rpc.svcgssd --user 0 + rm -f /var/run/rpc.svcgssd.pid + fi printf " nfsd" start-stop-daemon --stop --oknodo --quiet \ --name nfsd --user 0 --signal 2 diff -puN /dev/null debian/nfs-kernel-server.NEWS --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.NEWS 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,8 @@ +nfs-utils (1:1.0.1-1) unstable; urgency=low + + * Exports default to "sync", that is, synchronous writes. + This is safer but MUCH SLOWER than the old default of "async". + All exports should be marked as either "sync" or "async" to + avoid a warning from exportfs. + + -- Chip Salzenberg Mon, 26 Aug 2002 12:17:57 -0400 diff -puN debian/nfs-kernel-server.postinst~CITI_NFS4_ALL debian/nfs-kernel-server.postinst --- nfs-utils-1.0.6/debian/nfs-kernel-server.postinst~CITI_NFS4_ALL 2004-10-27 18:02:44.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.postinst 2004-10-27 18:02:49.000000000 -0400 @@ -2,36 +2,26 @@ #DEBHELPER# -. /usr/share/debconf/confmodule - case "$1" in configure) - db_get nfs-kernel-server/tcpwrappers-mountd || true + for f in /var/lib/nfs/etab \ + /var/lib/nfs/rmtab \ + /var/lib/nfs/xtab; do + [ -e $f ] || touch $f + done - touch /var/lib/nfs/etab \ - /var/lib/nfs/rmtab \ - /var/lib/nfs/xtab + update-rc.d nfs-kernel-server defaults 20 80 >/dev/null - if test -s /etc/exports - then - : do nothing - else - cat </etc/exports -# /etc/exports: the access control list for filesystems which may be exported -# to NFS clients. See exports(5). -EOF + # Remove obsolete debconf questions + if [ -e /usr/share/debconf/confmodule ]; then + . /usr/share/debconf/confmodule + db_unregister nfs-kernel-server/sync-default || true + db_unregister nfs-kernel-server/tcpwrappers-mountd || true + db_stop fi - - # The old nfs-server's init script can't tell that it's been - # removed, so we have to kill the symlinks to it. - update-rc.d -f nfs-server remove >/dev/null - - update-rc.d nfs-kernel-server defaults 20 80 >/dev/null ;; esac -db_stop - act="restart" [ "$1:$2" = "configure:" ] && act="start" invoke-rc.d nfs-kernel-server $act diff -puN debian/nfs-kernel-server.postrm~CITI_NFS4_ALL debian/nfs-kernel-server.postrm --- nfs-utils-1.0.6/debian/nfs-kernel-server.postrm~CITI_NFS4_ALL 2004-10-27 18:02:44.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/nfs-kernel-server.postrm 2004-10-27 18:02:49.000000000 -0400 @@ -5,6 +5,10 @@ case "$1" in purge) update-rc.d nfs-kernel-server remove >/dev/null + + rm -f /var/lib/nfs/etab \ + /var/lib/nfs/rmtab \ + /var/lib/nfs/xtab ;; esac diff -L debian/nfs-kernel-server.templates -puN debian/nfs-kernel-server.templates~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/debian/nfs-kernel-server.templates +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,17 +0,0 @@ -Template: nfs-kernel-server/sync-default -Type: note -_Description: NFS server defaults to synchronous writes - To comply with standards and increase data safety, the Linux NFS server - now defaults to synchronous writes. Since this is a major change, it is - not silent: All exports should be explicitly marked as either "sync" or - "async". Exports not so marked will elicit warnings. - -Template: nfs-kernel-server/tcpwrappers-mountd -Type: note -_Description: in /etc/hosts.{allow,deny}, replace "rpc.mountd" with "mountd" - The mount daemon uses tcpwrappers to control access. To configure it, use - program name "mountd" in /etc/hosts.allow and /etc/hosts.deny. - . - Older versions of nfs-kernel-server included a mount daemon that called - itself "rpc.mountd". Therefore, you should replace all occurrences of - "rpc.mountd" with "mountd" in /etc/hosts.allow and /etc/hosts.deny. diff -puN debian/rules~CITI_NFS4_ALL debian/rules --- nfs-utils-1.0.6/debian/rules~CITI_NFS4_ALL 2004-10-27 18:02:44.000000000 -0400 +++ nfs-utils-1.0.6-bfields/debian/rules 2004-10-27 18:02:49.000000000 -0400 @@ -13,6 +13,13 @@ DEBTMP := $(shell pwd)/debian/tmp build: build-stamp build-stamp: + # Debian source diffs don't reflect removals. + # This kludge will suffice until the next upstream version. *sigh* + rm -f debian/nfs-common.config \ + debian/nfs-common.templates \ + debian/nfs-kernel-server.config \ + debian/nfs-kernel-server.templates + dh_testdir # Add here commands to compile the package. $(SETGCC) ./configure \ @@ -39,6 +46,7 @@ binary-arch: build dh_testroot dh_clean -k dh_installdirs + dh_install # Add here commands to install the files into debian/tmp $(MAKE) install_prefix='$(DEBTMP)' install dh_movefiles @@ -51,7 +59,8 @@ binary-arch: build done; \ rm -f tmp/usr/sbin/*quota*; \ rm -f tmp/usr/share/man/man8/*quota*; \ - rm -rf tmp/var/lib/nfs/* + rm -rf tmp/var/lib/nfs/*; \ + cp --preserve=timestamps etc.exports tmp/etc/exports # Fixups End Here # dh_installdocs -A README dh_installexamples diff -L etc/nodist/nfs-server -puN etc/nodist/nfs-server~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/etc/nodist/nfs-server +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,129 +0,0 @@ -#!/bin/sh -# nfs This shell script starts and stops the nfs services in a distribution -# independent fashion. -# -# description: starts and stops nfs server services -# chkconfig: 2345 60 20 -# -# Copyright (c) 2000-2001 Mission Critical Linux, Inc. -# - -PATH=/sbin:/bin:/usr/sbin:/usr/bin -export PATH - -# Who am I? -SCRIPT_NAME=`basename $0` - -# Grab our daemon functions. -. `dirname $0`/nfs-functions - -# Kernel daemons and options -PREFIX="rpc." # Prefix for kernel execs (usually "rpc.") -NFSD="nfsd" # Kernel NFS Server -RPCNFSDCOUNT="8" # Number of nfsd threads - -# User daemons and options -RQUOTAD="rpc.rquotad" # Remote quota server -MOUNTD="rpc.mountd" # Mount server -RPCMOUNTDOPTS="" # options for rpc.mountd -EXPORTFS="exportfs" # Exportfs command - -SCRIPT_NAME=`basename $0` -DESC="NFS kernel daemon" - -# We use "type -path" instead of "which" since it's internal to bash. -[ -x "`type -path $PREFIX$NFSD`" ] || exit 0 -[ -x "`type -path $MOUNTD`" ] || exit 0 - -# Also make sure we have our exportfs command. -[ -x "`type -path $EXPORTFS`" ] || exit 0 -[ -s /etc/exports ] || exit 0 - -# rquotad is not required for NFS to work, however. -# Unset if it is not present. -[ -x "`type -path $RQUOTAD`" ] || unset RQUOTAD - -# Handle how we were called. -case "$1" in -start) - echo -n "Exporting directories for $DESC..." - $EXPORTFS -r - echo "done." - - echo -n "Starting $NFSD: " - startdaemon $PREFIX$NFSD $RPCNFSDCOUNT - - # Disable NFSv3 on mountd if we don't have NFSv3 - ClearAddr= - if [ -f /proc/net/rpc/auth.unix.ip/channel ] ; then - if grep -s 127.0.0.1 /proc/net/rpc/auth.unix.ip/content > /dev/null ; then - : address already known - else - echo nfsd 127.0.0.1 2147483647 localhost > /proc/net/rpc/auth.unix.ip/channel - ClearAddr= - fi - fi - rpcinfo -u localhost nfs 3 &>/dev/null - if [ "$?" != "0" ] - then - RPCMOUNTDOPTS="$RPCMOUNTDOPTS --no-nfs-version 3" - fi - if [ -n "$ClearAddr" ]; then - echo nfsd 127.0.0.1 1 > /proc/net/rpc/auth.unix.ip/channel - fi - - echo -n "Starting $MOUNTD: " - startdaemon $MOUNTD $RPCMOUNTDOPTS - - # Start rquotad if it is set - if [ -n "$RQUOTAD" ] - then - echo -n "Starting $RQUOTAD: " - startdaemon $RQUOTAD - fi - - # if this lock file doesn't exist, init won't even try to run - # the shutdown script for this service on RedHat systems! - # on non-RedHat systems, /var/lock/subsys may not exist. - touch /var/lock/subsys/$SCRIPT_NAME &> /dev/null - ;; - -stop) - for process in $RQUOTAD $MOUNTD $NFSD - do - echo -n "Stopping $process: " - stopdaemon $process - done - - echo "Unexporting directories for $DESC..." - $EXPORTFS -au - rm -f /var/lock/subsys/$SCRIPT_NAME - echo "done." - ;; - -restart) - $0 stop - $0 start - ;; - -reload) - # Update exports - echo "Re-exporting directories for $DESC..." - $EXPORTFS -r - touch /var/lock/subsys/$SCRIPT_NAME &> /dev/null - echo "done." - ;; - -status) - # First, check status of userland daemons - for process in $RQUOTAD $MOUNTD $NFSD - do - daemonstatus $process - done - exit 0 - ;; - -*) - echo "Usage: $0 {start|stop|status|restart|reload}" - exit 1 -esac diff -L etc/redhat/nfs -puN etc/redhat/nfs~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/etc/redhat/nfs +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,31 +0,0 @@ -# For more information on nfs tuning, please see the NFS-HOWTO -# http://nfs.sourceforge.net/nfs-howto/ - -# Pass any additional options for mountd. -# MOUNTD_OPTIONS= - -# Pin mountd to a given port rather than random one from portmapper -# MOUNTD_PORT= - -# Don't advertise TCP for mount. -# MOUNTD_TCP=no - -# NFS V3 -# MOUNTD_NFS_V3=auto|yes|no - -# NFS V2 -# MOUNTD_NFS_V2=auto|yes|no - -# The number of open file descriptors -# MOUNTD_OPEN_FILES=128 - -# Pass the number of instances of nfsd (8 is default; 16 or more -# might be needed to handle heavy client traffic) -# NFSDCOUNT=8 - -# Increase the memory limits on the socket input queues for -# the nfs processes .. NFS benchmark SPECsfs demonstrate a -# need for a larger than default size (64kb) .. setting -# TUNE_QUEUE to yes will set the values to 256kb. -# TUNE_QUEUE="yes" -# NFS_QS=262144 diff -L etc/redhat/nfs.init -puN etc/redhat/nfs.init~CITI_NFS4_ALL /dev/null --- nfs-utils-1.0.6/etc/redhat/nfs.init +++ /dev/null 2004-08-19 17:44:20.000000000 -0400 @@ -1,182 +0,0 @@ -#!/bin/sh -# -# nfs This shell script takes care of starting and stopping -# the NFS services. -# -# chkconfig: - 60 20 -# description: NFS is a popular protocol for file sharing across TCP/IP \ -# networks. This service provides NFS server functionality, \ -# which is configured via the /etc/exports file. -# probe: true -# config: /etc/sysconfig/nfs - -# Source function library. -. /etc/rc.d/init.d/functions - -# Source networking configuration. -if [ ! -f /etc/sysconfig/network ]; then - exit 0 -fi - -. /etc/sysconfig/network - -# Check that networking is up. -[ ${NETWORKING} = "no" ] && exit 0 - -[ -x /usr/sbin/rpc.nfsd ] || exit 0 -[ -x /usr/sbin/rpc.mountd ] || exit 0 -[ -x /usr/sbin/exportfs ] || exit 0 -[ -s /etc/exports ] || exit 0 - -# Check for and source configuration file otherwise set defaults -# TUNE_QUEUE: controls whether to up the size of input queues -[ -f /etc/sysconfig/nfs ] && . /etc/sysconfig/nfs - -[ -z "$MOUNTD_NFS_V2" ] && MOUNTD_NFS_V2=auto -[ -z "$MOUNTD_NFS_V3" ] && MOUNTD_NFS_V3=auto - -# Number of servers to be started by default -[ -z "$NFSDCOUNT" ] && NFSDCOUNT=8 - -# Remote quota server -[ -z "$RQUOTAD" ] && RQUOTAD=`type -path rpc.rquotad` - -# Get the initial values for the input sock queues -# at the time of running the script. -if [ "$TUNE_QUEUE" = "yes" ]; then - RMEM_DEFAULT=`/sbin/sysctl -n net.core.rmem_default` - RMEM_MAX=`/sbin/sysctl -n net.core.rmem_max` - # 256kb recommended minimum size based on SPECsfs NFS benchmarks - [ -z "$NFS_QS" ] && NFS_QS=262144 -fi - -# See how we were called. -case "$1" in - start) - # Start daemons. - # Apply input queue increase for nfs server - if [ "$TUNE_QUEUE" = "yes" ]; then - /sbin/sysctl -w net.core.rmem_default=$NFSD_QS >/dev/null 2>&1 - /sbin/sysctl -w net.core.rmem_max=$NFSD_QS >/dev/null 2>&1 - fi - action "Starting NFS services: " /usr/sbin/exportfs -r - if [ -n "$RQUOTAD" -a "$RQUOTAD" != "no" ]; then - echo -n "Starting NFS quotas: " - daemon rpc.rquotad - echo - fi - echo -n "Starting NFS daemon: " - daemon rpc.nfsd $NFSDCOUNT - echo - - [ -n "$MOUNTD_PORT" ] \ - && MOUNTD_OPTIONS="$MOUNTD_OPTIONS -p $MOUNTD_PORT" - [ "$MOUNTD_TCP" = "no" -o "$MOUNTD_TCP" = "NO" ] \ - && MOUNTD_OPTIONS="$MOUNTD_OPTIONS --no-tcp" - - case $MOUNTD_NFS_V2 in - auto|AUTO) - # Let's see if we support NFS version 2. - ClearAddr= - if [ -f /proc/net/rpc/auth.unix.ip/channel ] ; then - if grep -s 127.0.0.1 /proc/net/rpc/auth.unix.ip/content > /dev/null ; then - : address already known - else - echo nfsd 127.0.0.1 2147483647 localhost > /proc/net/rpc/auth.unix.ip/channel - ClearAddr=yes - fi - fi - /usr/sbin/rpcinfo -u localhost nfs 2 &>/dev/null - if [ $? -ne 0 ]; then - MOUNTD_OPTIONS="$MOUNTD_OPTIONS --no-nfs-version 2" - fi - if [ -n "$ClearAddr" ]; then - echo nfsd 127.0.0.1 1 > /proc/net/rpc/auth.unix.ip/channel - fi - ;; - no|NO) - MOUNTD_OPTIONS="$MOUNTD_OPTIONS --no-nfs-version 2" - ;; - yes|YES) - MOUNTD_OPTIONS="$MOUNTD_OPTIONS --nfs-version 2" - ;; - esac - - case $MOUNTD_NFS_V3 in - auto|AUTO) - # Let's see if we support NFS version 3. - /usr/sbin/rpcinfo -u localhost nfs 3 &>/dev/null - if [ $? -ne 0 ]; then - MOUNTD_OPTIONS="$MOUNTD_OPTIONS --no-nfs-version 3" - fi - ;; - no|NO) - MOUNTD_OPTIONS="$MOUNTD_OPTIONS --no-nfs-version 3" - ;; - yes|YES) - MOUNTD_OPTIONS="$MOUNTD_OPTIONS --nfs-version 3" - ;; - esac - - echo -n "Starting NFS mountd: " - daemon rpc.mountd $MOUNTD_OPTIONS - echo - touch /var/lock/subsys/nfs - # reset input queue for rest of network services - if [ "$TUNE_QUEUE" = "yes" ]; then - /sbin/sysctl -w net.core.rmem_default=$RMEM_DEFAULT >/dev/null 2>&1 - /sbin/sysctl -w net.core.rmem_max=$RMEM_MAX >/dev/null 2>&1 - fi - ;; - stop) - # Stop daemons. - echo -n "Shutting down NFS mountd: " - killproc rpc.mountd - echo - echo -n "Shutting down NFS daemon: " - killproc nfsd - echo - if [ -n "$RQUOTAD" ]; then - echo -n "Shutting down NFS quotas: " - killproc rpc.rquotad - echo - fi - # Do it the last so that clients can still access the server - # when the server is running. - action "Shutting down NFS services: " /usr/sbin/exportfs -au - rm -f /var/lock/subsys/nfs - ;; - status) - status rpc.mountd - status nfsd - if [ -n "$RQUOTAD" ]; then - status rpc.rquotad - fi - ;; - restart) - $0 stop - $0 start - ;; - reload) - /usr/sbin/exportfs -r - touch /var/lock/subsys/nfs - ;; - probe) - if [ ! -f /var/lock/subsys/nfs ] ; then - echo start; exit 0 - fi - /sbin/pidof rpc.mountd >/dev/null 2>&1; MOUNTD="$?" - /sbin/pidof nfsd >/dev/null 2>&1; NFSD="$?" - if [ $MOUNTD = 1 -o $NFSD = 1 ] ; then - echo restart; exit 0 - fi - if [ /etc/exports -nt /var/lock/subsys/nfs ] ; then - echo reload; exit 0 - fi - ;; - *) - echo "Usage: nfs {start|stop|status|restart|reload}" - exit 1 -esac - -exit 0 diff -L etc/redhat/rpcidmapd.init -puN /dev/null /dev/null diff -puN support/export/client.c~CITI_NFS4_ALL support/export/client.c --- nfs-utils-1.0.6/support/export/client.c~CITI_NFS4_ALL 2004-10-27 18:02:44.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/export/client.c 2004-10-27 18:02:49.000000000 -0400 @@ -392,6 +392,8 @@ client_check(nfs_client *clp, struct hos #endif case MCL_ANONYMOUS: return 1; + case MCL_GSS: + return 0; default: xlog(L_FATAL, "internal: bad client type %d", clp->m_type); } @@ -425,6 +427,8 @@ client_gettype(char *ident) if (ident[0] == '\0' || strcmp(ident, "*")==0) return MCL_ANONYMOUS; + if (strncmp(ident, "gss/", 4) == 0) + return MCL_GSS; if (ident[0] == '@') { #ifndef HAVE_INNETGR xlog(L_WARNING, "netgroup support not compiled in"); diff -puN support/export/nfsctl.c~CITI_NFS4_ALL support/export/nfsctl.c --- nfs-utils-1.0.6/support/export/nfsctl.c~CITI_NFS4_ALL 2004-10-27 18:02:44.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/export/nfsctl.c 2004-10-27 18:02:49.000000000 -0400 @@ -27,7 +27,7 @@ export_export(nfs_export *exp) struct nfsctl_export exparg; struct nfsctl_client cltarg; - if (!clp->m_exported) { + if (!clp->m_exported && (clp->m_type != MCL_GSS)) { if (!cltsetup(&cltarg, clp)) return 0; if (nfsaddclient(&cltarg) < 0) diff -puN /dev/null support/gssapi/g_accept_sec_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_accept_sec_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,213 @@ +/* #ident "@(#)gss_accept_sec_context.c 1.19 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_accept_sec_context + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include + +OM_uint32 KRB5_CALLCONV +gss_accept_sec_context (minor_status, + context_handle, + verifier_cred_handle, + input_token_buffer, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle) + +OM_uint32 * minor_status; +gss_ctx_id_t * context_handle; +gss_cred_id_t verifier_cred_handle; +gss_buffer_t input_token_buffer; +gss_channel_bindings_t input_chan_bindings; +gss_name_t * src_name; +gss_OID * mech_type; +gss_buffer_t output_token; +OM_uint32 * ret_flags; +OM_uint32 * time_rec; +gss_cred_id_t * delegated_cred_handle; + +{ + OM_uint32 status, temp_status, temp_minor_status; + gss_union_ctx_id_t union_ctx_id; + gss_union_cred_t union_cred; + gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL; + gss_name_t internal_name; + gss_OID_desc token_mech_type_desc; + gss_OID token_mech_type = &token_mech_type_desc; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + /* + * if context_handle is GSS_C_NO_CONTEXT, allocate a union context + * descriptor to hold the mech type information as well as the + * underlying mechanism context handle. Otherwise, cast the + * value of *context_handle to the union context variable. + */ + + if(*context_handle == GSS_C_NO_CONTEXT) { + + /* Get the token mech type */ + status = __gss_get_mech_type(token_mech_type, input_token_buffer); + if (status) + return status; + + status = GSS_S_FAILURE; + union_ctx_id = (gss_union_ctx_id_t) + malloc(sizeof(gss_union_ctx_id_desc)); + if (!union_ctx_id) { + *minor_status = ENOMEM; + goto error_out; + } + + union_ctx_id->mech_type = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!union_ctx_id->mech_type) { + *minor_status = ENOMEM; + goto error_out; + } + + union_ctx_id->mech_type->elements = (void *) + malloc(token_mech_type->length); + if (!union_ctx_id->mech_type->elements) { + *minor_status = ENOMEM; + goto error_out; + } + + union_ctx_id->mech_type->length = token_mech_type->length; + memcpy(union_ctx_id->mech_type->elements, + token_mech_type->elements, + token_mech_type->length); + + /* copy the supplied context handle */ + + union_ctx_id->internal_ctx_id = *context_handle; + } else { + union_ctx_id = *context_handle; + token_mech_type = union_ctx_id->mech_type; + } + + /* + * get the appropriate cred handle from the union cred struct. + * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will + * use the default credential. + */ + union_cred = (gss_union_cred_t) verifier_cred_handle; + input_cred_handle = __gss_get_mechanism_cred(union_cred, token_mech_type); + + /* + * now select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (token_mech_type); + if (mech && mech->gss_accept_sec_context) { + + status = mech->gss_accept_sec_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + &union_ctx_id->internal_ctx_id, + input_cred_handle, + input_token_buffer, + input_chan_bindings, + &internal_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle); + + /* If there's more work to do, keep going... */ + if (status == GSS_S_CONTINUE_NEEDED) + return GSS_S_CONTINUE_NEEDED; + + /* if the call failed, return with failure */ + if (status != GSS_S_COMPLETE) + goto error_out; + + /* + * if src_name is non-NULL, + * convert internal_name into a union name equivalent + * First call the mechanism specific display_name() + * then call gss_import_name() to create + * the union name struct cast to src_name + */ +#if 0 + /* ANDROS: src_name is never null, it is a ptr from the gss_accept_sec_context + * caller. internal_name may or may not be set by the mechanism. so, don't + * call __gss_convert_name_to_union_name which sets the src_name + * unless the internal name is set + * by the above mech->gss_accept_sec_context. + */ + if (internal_name != NULL && status == GSS_S_COMPLETE) { +#else + if (src_name != NULL && status == GSS_S_COMPLETE) { +#endif + temp_status = __gss_convert_name_to_union_name( + &temp_minor_status, mech, internal_name, src_name); + if (temp_status != GSS_S_COMPLETE) { + if (minor_status) + *minor_status = temp_minor_status; + gss_release_buffer(&temp_minor_status, output_token); + __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, &internal_name); + return (temp_status); + } + } + + if(*context_handle == GSS_C_NO_CONTEXT) + *context_handle = (gss_ctx_id_t *) union_ctx_id; + + return(status); + } + + return(GSS_S_BAD_MECH); + +error_out: + if (union_ctx_id) { + if (union_ctx_id->mech_type) { + if (union_ctx_id->mech_type->elements) + free(union_ctx_id->mech_type->elements); + free(union_ctx_id->mech_type); + } + free(union_ctx_id); + } + return (status); +} + diff -puN /dev/null support/gssapi/g_acquire_cred.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_acquire_cred.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,539 @@ +/* #ident "@(#)gss_acquire_cred.c 1.19 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_acquire_cred + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +static gss_OID_set +create_actual_mechs(creds) + gss_union_cred_t creds; +{ + gss_OID_set actual_mechs; + int i; + + actual_mechs = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)); + if (!actual_mechs) + return NULL; + + actual_mechs->elements = (gss_OID) + malloc(sizeof(gss_OID_desc) * creds->count); + if (!actual_mechs->elements) { + free(actual_mechs); + return NULL; + } + + actual_mechs->count = creds->count; + + for (i=0; i < creds->count; i++) { + actual_mechs->elements[i].length = creds->mechs_array[i].length; + actual_mechs->elements[i].elements = (void *) + malloc(creds->mechs_array[i].length); + memcpy(actual_mechs->elements[i].elements, + creds->mechs_array[i].elements, creds->mechs_array[i].length); + } + + return actual_mechs; +} + + +OM_uint32 KRB5_CALLCONV +gss_acquire_cred(minor_status, + desired_name, + time_req, + desired_mechs, + cred_usage, + output_cred_handle, + actual_mechs, + time_rec) + +OM_uint32 * minor_status; +gss_name_t desired_name; +OM_uint32 time_req; +gss_OID_set desired_mechs; +int cred_usage; +gss_cred_id_t * output_cred_handle; +gss_OID_set * actual_mechs; +OM_uint32 * time_rec; + +{ + OM_uint32 status, temp_minor_status, temp_time_rec = ~0; + unsigned int i, j, creds_acquired = 0; + int k; + gss_union_name_t union_name; + gss_name_t internal_name; + gss_union_cred_t creds; + gss_OID_set_desc default_OID_set; + gss_OID_desc default_OID; + gss_OID specific_mech_type = 0; + gss_mechanism mech; + + /* + * This struct is used to keep track of which mech_types are + * actually available and to store the credentials returned + * from them by each mechanism specific gss_acquire_cred() call. + * The results are used to construct the final union_cred + * structure returned by the glue layer gss_acquire_cred() call + * and the actual_mechs gss_OID_set returned. + */ + + struct creds_returned { + unsigned char available; + gss_cred_id_t cred; + } *creds_returned; + + gss_initialize(); + + /* Set this to NULL for now */ + + if (actual_mechs) + *actual_mechs = GSS_C_NULL_OID_SET; + + if (minor_status) + *minor_status = 0; + + /* No need to continue if we don't have a place to store the creds */ + if (output_cred_handle == NULL) + return GSS_S_COMPLETE; + + /* get desired_name cast as a union_name type */ + + union_name = (gss_union_name_t) desired_name; + + if (union_name) + specific_mech_type = union_name->mech_type; + + /* + * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an + * appropriate default. + */ + if(desired_mechs == GSS_C_NULL_OID_SET) { + /* + * If union_name->mech_type is NULL then we get the default + * mechanism; otherwise, we get the mechanism for the + * mechanism-specific name. + */ + mech = __gss_get_mechanism(specific_mech_type); + if (mech == NULL) + return (GSS_S_BAD_MECH); + + desired_mechs = &default_OID_set; + default_OID_set.count = 1 ; + default_OID_set.elements = &default_OID; + default_OID.length = mech->mech_type.length; + default_OID.elements = mech->mech_type.elements; + } + + /* + * Now allocate the creds returned array. There is one element + * for each member of the desired_mechs argument. + */ + + creds_returned = (struct creds_returned *) + malloc(sizeof(struct creds_returned) * desired_mechs->count); + + /* + * For each requested mechanism in desired_mechs, determine if it + * is supported. If so, mark the corresponding element in + * creds_returned->available as 1 and call the mechanism + * specific gss_acquire_cred(), placing the returned cred in + * creds_returned->cred. If not, mark creds_returned->available as + * 0. + */ + status = GSS_S_BAD_MECH; + for (j=0; j < desired_mechs->count; j++) { + creds_returned[j].available = 0; + + mech = __gss_get_mechanism (&desired_mechs->elements[j]); + if (!mech || !mech->gss_acquire_cred) + continue; + /* + * If this is a mechanism-specific name, then only use the + * mechanism of the name. + */ + if (specific_mech_type && !g_OID_equal(specific_mech_type, + &mech->mech_type)) + continue; + /* + * If this is not a mechanism-specific name, then we need to + * do an import the external name in union_name first. + */ + if (union_name == 0) + internal_name = (gss_name_t) 0; + else if (!union_name->mech_type) { + if (__gss_import_internal_name(&temp_minor_status, + &mech->mech_type, + union_name, &internal_name)) { + continue; + } + } else + internal_name = union_name->mech_name; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_acquire_cred(mech->context, minor_status, +#else + status = mech->gss_acquire_cred(minor_status, +#endif + internal_name, time_req, + desired_mechs, cred_usage, + &creds_returned[j].cred, + NULL, &temp_time_rec); + + /* Release the internal name, if allocated above */ + if (union_name && !union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, + &internal_name); + } + + if (status != GSS_S_COMPLETE) + continue; + + /* + * Add this into the creds_returned structure, if we got + * a good credential for this mechanism. + */ + if (time_rec) { + *time_rec = *time_rec > temp_time_rec ? temp_time_rec : *time_rec; + temp_time_rec = *time_rec; + } + + creds_returned[j].available = 1; + creds_acquired++; + + /* + * If union_name is set, then we're done. Continue, and + * declare success. Otherwise, if do an inquire credentials + * from the first mechanism that succeeds and use that as the + * union name. + */ + if (union_name) + continue; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_inquire_cred(mech->context, &temp_minor_status, +#else + status = mech->gss_inquire_cred(&temp_minor_status, +#endif + creds_returned[j].cred, + &internal_name, 0, 0, 0); + if (status) { + /* Should never happen */ + creds_returned[j].available = 0; + creds_acquired--; + if (mech->gss_release_cred) +#ifdef USE_MECH_CONTEXT + mech->gss_release_cred(mech->context, minor_status, +#else + mech->gss_release_cred(minor_status, +#endif + &creds_returned[j].cred); + continue; + } + + status = __gss_convert_name_to_union_name(&temp_minor_status, mech, + internal_name, + (gss_name_t *) &union_name); + } + + /* + * Now allocate the creds struct, which will be cast as a gss_cred_id_t + * and returned in the output_cred_handle argument. If there were + * no credentials found, return an error. Also, allocate the + * actual_mechs data. + */ + if (creds_acquired == 0) { + free (creds_returned); + return (status); + } + + creds = (gss_union_cred_t) malloc(sizeof(gss_union_cred_desc)); + + creds->count = creds_acquired; + + creds->mechs_array = (gss_OID) + malloc(sizeof(gss_OID_desc) * creds_acquired); + + creds->cred_array = (gss_cred_id_t *) + malloc(sizeof(gss_cred_id_t) * creds_acquired); + + if(actual_mechs != NULL) { + *actual_mechs = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)); + + (*actual_mechs)->count = creds_acquired; + + (*actual_mechs)->elements = (gss_OID) + malloc(sizeof(gss_OID_desc) * creds_acquired); + } + + /* + * copy the mechanisms found and their allocated credentials into the + * creds structure. At the same time, build up the actual_mechs + * data. + */ + + j = 0; + + for (i=0; icount; i++) { + if(creds_returned[i].available) { + + creds->mechs_array[j].length = + desired_mechs->elements[i].length; + creds->mechs_array[j].elements = (void *) + malloc(desired_mechs->elements[i].length); + memcpy(creds->mechs_array[j].elements, + desired_mechs->elements[i].elements, + desired_mechs->elements[i].length); + creds->cred_array[j] = creds_returned[i].cred; + if (actual_mechs) { + (*actual_mechs)->elements[j].length = + desired_mechs->elements[i].length; + (*actual_mechs)->elements[j].elements = (void *) + malloc(desired_mechs->elements[i].length); + memcpy((*actual_mechs)->elements[j].elements, + desired_mechs->elements[i].elements, + desired_mechs->elements[i].length); + } + j++; + } + } + + /* free the creds_returned struct, since we are done with it. */ + + free(creds_returned); + + /* record the information needed for gss_inquire_cred() */ + + creds->auxinfo.creation_time = time(0); + creds->auxinfo.time_rec = temp_time_rec; + creds->auxinfo.cred_usage = cred_usage; + + /* + * we can't just record the internal name, desired_name, since + * it may be destroyed between now and the time gss_inquire_cred() + * is called. So we must record the printable name in a + * gss_buffer_t, calling gss_display_name() to fill it in. When + * gss_inquire_name() is called, we must then call gss_import_name() + * to get the internal name that is required at that point. + */ + if (desired_name) { + status = gss_display_name(&temp_minor_status, desired_name, + &creds->auxinfo.name, + &creds->auxinfo.name_type); + if (status) { + status = GSS_S_BAD_NAME; + goto error_out; + } + } else { + status = gss_display_name(&temp_minor_status, union_name, + &creds->auxinfo.name, + &creds->auxinfo.name_type); + if (status) { + status = GSS_S_BAD_NAME; + goto error_out; + } + } + + *output_cred_handle = (gss_cred_id_t) creds; + return(GSS_S_COMPLETE); + +error_out: + for (k=0; k < creds->count; k++) { + free(creds->mechs_array[k].elements); + if (actual_mechs) + free((*actual_mechs)->elements[k].elements); + } + + if (actual_mechs) { + free((*actual_mechs)->elements); + free(*actual_mechs); + *actual_mechs = GSS_C_NULL_OID_SET; + } + free(creds->cred_array); + free(creds->mechs_array); + free(creds); + + return(status); +} + +/* V2 KRB5_CALLCONV */ +OM_uint32 KRB5_CALLCONV +gss_add_cred(minor_status, input_cred_handle, + desired_name, desired_mech, cred_usage, + initiator_time_req, acceptor_time_req, + output_cred_handle, actual_mechs, + initiator_time_rec, acceptor_time_rec) + OM_uint32 *minor_status; + gss_cred_id_t input_cred_handle; + gss_name_t desired_name; + gss_OID desired_mech; + gss_cred_usage_t cred_usage; + OM_uint32 initiator_time_req; + OM_uint32 acceptor_time_req; + gss_cred_id_t *output_cred_handle; + gss_OID_set *actual_mechs; + OM_uint32 *initiator_time_rec; + OM_uint32 *acceptor_time_rec; +{ + OM_uint32 status, temp_minor_status; + OM_uint32 time_req, time_rec; + gss_union_name_t union_name; + gss_union_cred_t new_union_cred, union_cred; + gss_name_t internal_name; + gss_mechanism mech; + gss_cred_id_t cred; + gss_OID new_mechs_array; + gss_cred_id_t * new_cred_array; + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_NO_CRED; + + union_cred = (gss_union_cred_t) input_cred_handle; + + mech = __gss_get_mechanism(desired_mech); + if (!mech) + return GSS_S_BAD_MECH; + + if (__gss_get_mechanism_cred(union_cred, desired_mech) != + GSS_C_NO_CREDENTIAL) + return GSS_S_DUPLICATE_ELEMENT; + + union_name = (gss_union_name_t) desired_name; + if (union_name->mech_type) { + if (!g_OID_equal(desired_mech, union_name->mech_type)) + return GSS_S_BAD_NAMETYPE; + internal_name = union_name->mech_name; + } else { + if (__gss_import_internal_name(minor_status, desired_mech, + union_name, &internal_name)) + return (GSS_S_BAD_NAME); + } + + if (cred_usage == GSS_C_ACCEPT) + time_req = acceptor_time_req; + else if (cred_usage == GSS_C_INITIATE) + time_req = initiator_time_req; + else if (cred_usage == GSS_C_BOTH) + time_req = (acceptor_time_req > initiator_time_req) ? + acceptor_time_req : initiator_time_req; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_acquire_cred(mech->context, minor_status, +#else + status = mech->gss_acquire_cred(minor_status, +#endif + internal_name, time_req, + GSS_C_NULL_OID_SET, cred_usage, + &cred, NULL, &time_rec); + if (status != GSS_S_COMPLETE) + goto errout; + + new_mechs_array = (gss_OID) + malloc(sizeof(gss_OID_desc) * (union_cred->count+1)); + + new_cred_array = (gss_cred_id_t *) + malloc(sizeof(gss_cred_id_t) * (union_cred->count+1)); + + if (!new_mechs_array || !new_cred_array) { + *minor_status = ENOMEM; + status = GSS_S_FAILURE; + goto errout; + } + + + if (acceptor_time_rec) + if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) + *acceptor_time_rec = time_rec; + if (initiator_time_rec) + if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) + *initiator_time_rec = time_rec; + + /* + * OK, expand the mechanism array in the union credentials + * (Look for the union label...) + */ + memcpy(new_mechs_array, union_cred->mechs_array, + sizeof(gss_OID_desc) * union_cred->count); + memcpy(new_cred_array, union_cred->cred_array, + sizeof(gss_cred_id_t) * union_cred->count); + + new_cred_array[union_cred->count] = cred; + new_mechs_array[union_cred->count].length = desired_mech->length; + new_mechs_array[union_cred->count].elements = malloc(desired_mech->length); + if (!new_mechs_array[union_cred->count].elements) { + *minor_status = ENOMEM; + goto errout; + } + memcpy(new_mechs_array[union_cred->count].elements, desired_mech->elements, + desired_mech->length); + + if (output_cred_handle == NULL) { + free(union_cred->mechs_array); + free(union_cred->cred_array); + new_union_cred = union_cred; + } else { + new_union_cred = malloc(sizeof(gss_union_cred_desc)); + if (new_union_cred == NULL) { + *minor_status = ENOMEM; + goto errout; + } + *new_union_cred = *union_cred; + *output_cred_handle = new_union_cred; + } + new_union_cred->mechs_array = new_mechs_array; + new_union_cred->cred_array = new_cred_array; + new_union_cred->count++; + new_mechs_array = 0; + new_cred_array = 0; + + if (actual_mechs) + *actual_mechs = create_actual_mechs(new_union_cred); + + status = GSS_S_COMPLETE; + +errout: + if (new_mechs_array) + free(new_mechs_array); + if (new_cred_array) + free(new_cred_array); + if (!union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + desired_mech, &internal_name); + } + + return(status); +} diff -puN /dev/null support/gssapi/g_compare_name.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_compare_name.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,165 @@ +/* #ident "@(#)gss_compare_name.c 1.13 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_compare_name + * + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +OM_uint32 KRB5_CALLCONV +gss_compare_name (minor_status, + name1, + name2, + name_equal) + +OM_uint32 * minor_status; +gss_name_t name1; +gss_name_t name2; +int * name_equal; + +{ + OM_uint32 major_status, temp_minor; + gss_union_name_t union_name1, union_name2; + gss_mechanism mech; + gss_name_t internal_name; + + gss_initialize(); + + if (name1 == 0 || name2 == 0) { + if (name_equal) + *name_equal = 0; + return GSS_S_BAD_NAME; + } + + union_name1 = (gss_union_name_t) name1; + union_name2 = (gss_union_name_t) name2; + /* + * Try our hardest to make union_name1 be the mechanism-specific + * name. (Of course we can't if both names aren't + * mechanism-specific.) + */ + if (union_name1->mech_type == 0) { + union_name1 = (gss_union_name_t) name2; + union_name2 = (gss_union_name_t) name1; + } + /* + * If union_name1 is mechanism specific, then fetch its mechanism + * information. + */ + if (union_name1->mech_type) { + mech = __gss_get_mechanism (union_name1->mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_compare_name) + return (GSS_S_BAD_BINDINGS); + } + + if (name_equal == NULL) + return GSS_S_COMPLETE; + + *name_equal = 0; /* Default to *not* equal.... */ + + /* + * First case... both names are mechanism-specific + */ + if (union_name1->mech_type && union_name2->mech_type) { + if (!g_OID_equal(union_name1->mech_type, union_name2->mech_type)) + return (GSS_S_COMPLETE); + if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0)) + /* should never happen */ + return (GSS_S_BAD_NAME); +#ifdef USE_MECH_CONTEXT + return (mech->gss_compare_name(mech->context, minor_status, +#else + return (mech->gss_compare_name(minor_status, +#endif + union_name1->mech_name, + union_name2->mech_name, name_equal)); + + } + + /* + * Second case... both names are NOT mechanism specific. + * + * All we do here is make sure the two name_types are equal and then + * that the external_names are equal. Note the we do not take care + * of the case where two different external names map to the same + * internal name. We cannot determine this, since we as yet do not + * know what mechanism to use for calling the underlying + * gss_import_name(). + */ + if (!union_name1->mech_type && !union_name2->mech_type) { + if (!g_OID_equal(union_name1->name_type, union_name2->name_type)) + return (GSS_S_COMPLETE); + if ((union_name1->external_name->length != + union_name2->external_name->length) || + (memcmp(union_name1->external_name->value, + union_name2->external_name->value, + union_name1->external_name->length) != 0)) + return (GSS_S_COMPLETE); + *name_equal = 1; + return (GSS_S_COMPLETE); + } + + /* + * Final case... one name is mechanism specific, the other isn't. + * + * We attempt to convert the general name to the mechanism type of + * the mechanism-specific name, and then do the compare. If we + * can't import the general name, then we return that the name is + * _NOT_ equal. + */ + if (union_name2->mech_type) { + /* We make union_name1 the mechanism specific name. */ + union_name1 = (gss_union_name_t) name2; + union_name2 = (gss_union_name_t) name1; + } + major_status = __gss_import_internal_name(minor_status, + union_name1->mech_type, + union_name2, + &internal_name); + if (major_status != GSS_S_COMPLETE) + return (GSS_S_COMPLETE); +#ifdef USE_MECH_CONTEXT + major_status = mech->gss_compare_name(mech->context, minor_status, +#else + major_status = mech->gss_compare_name(minor_status, +#endif + union_name1->mech_name, + internal_name, name_equal); + __gss_release_internal_name(&temp_minor, union_name1->mech_type, + &internal_name); + return (major_status); + +} diff -puN /dev/null support/gssapi/g_context_time.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_context_time.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,75 @@ +/* #ident "@(#)gss_context_time.c 1.8 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routines for gss_context_time + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_context_time (minor_status, + context_handle, + time_rec) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +OM_uint32 * time_rec; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_context_time) + status = mech->gss_context_time( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + time_rec); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff -puN /dev/null support/gssapi/g_delete_sec_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_delete_sec_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,88 @@ +/* #ident "@(#)gss_delete_sec_context.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_delete_sec_context + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +OM_uint32 KRB5_CALLCONV +gss_delete_sec_context (minor_status, + context_handle, + output_token) + +OM_uint32 * minor_status; +gss_ctx_id_t * context_handle; +gss_buffer_t output_token; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + /* if the context_handle is Null, return NO_CONTEXT error */ + + if(context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) + return(GSS_S_NO_CONTEXT); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) *context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_delete_sec_context) + status = mech->gss_delete_sec_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + &ctx->internal_ctx_id, + output_token); + else + status = GSS_S_BAD_BINDINGS; + + /* now free up the space for the union context structure */ + + free(ctx->mech_type->elements); + free(ctx->mech_type); + free(*context_handle); + *context_handle = NULL; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff -puN /dev/null support/gssapi/g_dsp_name.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_dsp_name.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,96 @@ +/* #ident "@(#)g_dsp_name.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_display_name() + * + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +OM_uint32 KRB5_CALLCONV +gss_display_name (minor_status, + input_name, + output_name_buffer, + output_name_type) + +OM_uint32 * minor_status; +gss_name_t input_name; +gss_buffer_t output_name_buffer; +gss_OID * output_name_type; + +{ + OM_uint32 major_status; + gss_union_name_t union_name; + + if (input_name == 0) + return GSS_S_BAD_NAME; + + union_name = (gss_union_name_t) input_name; + + if (union_name->mech_type) { + /* + * OK, we have a mechanism-specific name; let's use it! + */ + return (__gss_display_internal_name(minor_status, + union_name->mech_type, + union_name->mech_name, + output_name_buffer, + output_name_type)); + } + + /* + * copy the value of the external_name component of the union + * name into the output_name_buffer and point the output_name_type + * to the name_type component of union_name + */ + if (output_name_type != NULL) { + major_status = generic_gss_copy_oid(minor_status, + union_name->name_type, + output_name_type); + if (major_status) + return (major_status); + } + + if (output_name_buffer != NULL) { + output_name_buffer->length = union_name->external_name->length; + + output_name_buffer->value = + (void *) malloc(output_name_buffer->length); + + memcpy(output_name_buffer->value, + union_name->external_name->value, + output_name_buffer->length); + } + + if (minor_status) + *minor_status = 0; + + return(GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_dsp_status.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_dsp_status.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,86 @@ +/* #ident "@(#)gss_display_status.c 1.8 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_display_status + * + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +OM_uint32 KRB5_CALLCONV +gss_display_status (minor_status, + status_value, + status_type, + req_mech_type, + message_context, + status_string) + +OM_uint32 * minor_status; +OM_uint32 status_value; +int status_type; +gss_OID req_mech_type; +OM_uint32 * message_context; +gss_buffer_t status_string; + +{ + OM_uint32 status; + gss_OID mech_type = (gss_OID) req_mech_type; + gss_mechanism mech; + + gss_initialize(); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (mech_type); + + if (mech == NULL) + return (GSS_S_BAD_MECH); + + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + if (mech->gss_display_status) + status = mech->gss_display_status( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + status_value, + status_type, + mech_type, + message_context, + status_string); + else + status = GSS_S_BAD_BINDINGS; + + return(status); +} diff -puN /dev/null support/gssapi/g_dup_name.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_dup_name.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,162 @@ +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * created andros 2.24.01 from g_compare_name.c + */ + +/* + * glue routine for gss_duplicate_name + * + */ + +#include +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include + +OM_uint32 KRB5_CALLCONV +gss_duplicate_name (minor_status, + in_name, + exp_name) +OM_uint32 * minor_status; +const gss_name_t in_name; +gss_name_t *exp_name; +{ + OM_uint32 tmp,major_status = GSS_S_COMPLETE; + gss_union_name_t union_in_name, union_exp_name; + gss_mechanism mech; + + gss_initialize(); + + /* if exp_name is NULL, simply return */ + if (exp_name == NULL) + return (GSS_S_COMPLETE); + + *exp_name = NULL; + + if (in_name == 0) + return (GSS_S_BAD_NAME); + + union_in_name = (gss_union_name_t) in_name; + + /* + * Create the union name struct that will hold the exported + * name and the name type. + */ + + union_exp_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_exp_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } +#ifdef DEBUG + fprintf(stderr, "gss_duplicate_name: copying *oid %p\n", + union_in_name->mech_type); +#endif + union_exp_name->gss_mech = union_in_name->gss_mech; + union_exp_name->mech_type = GSS_C_NO_OID; + if (union_in_name->mech_type != GSS_C_NO_OID && + (generic_gss_copy_oid(&tmp, union_in_name->mech_type, + &union_exp_name->mech_type) != GSS_S_COMPLETE)) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_exp_name->mech_name = NULL; + union_exp_name->name_type = GSS_C_NO_OID; + if (union_in_name->name_type != GSS_C_NO_OID && + (generic_gss_copy_oid(&tmp, union_in_name->name_type, + &union_exp_name->name_type) != GSS_S_COMPLETE)) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_exp_name->external_name = NULL; + union_exp_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_exp_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_exp_name->external_name->length = union_in_name->external_name->length; + /* + * we malloc length+1 to stick a NULL on the end, just in case + * Note that this NULL is not included in ->length for a reason! + */ + + union_exp_name->external_name->value = + (void *) malloc(union_in_name->external_name->length); + if (!union_exp_name->external_name->value) { + *minor_status = ENOMEM; + goto allocation_failure; + } + memcpy(union_exp_name->external_name->value, + union_in_name->external_name->value, + union_exp_name->external_name->length); + + /* + * Mechanism specific name + */ + + if (union_in_name->mech_type != GSS_C_NO_OID) { + mech = __gss_get_mechanism (union_in_name->mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_duplicate_name) + return (GSS_S_BAD_BINDINGS); + +#ifdef USE_MECH_CONTEXT + major_status = mech->gss_duplicate_name(mech->context, minor_status, +#else + major_status = mech->gss_duplicate_name(minor_status, +#endif + union_in_name->mech_name, &union_exp_name->mech_name); + if (major_status != GSS_S_COMPLETE) + return (major_status); + } +#ifdef DEBUG + fprintf(stderr, "gss_duplicate_name: returning union_exp_name %p\n", + union_exp_name); +#endif + *exp_name = union_exp_name; + return (major_status); + +allocation_failure: + if (union_exp_name) { + if (union_exp_name->external_name) { + if (union_exp_name->external_name->value) + free(union_exp_name->external_name->value); + free(union_exp_name->external_name); + } + if (union_exp_name->name_type) + generic_gss_release_oid(&tmp, &union_exp_name->name_type); + if (union_exp_name->mech_name) + __gss_release_internal_name(minor_status, union_exp_name->mech_type, + &union_exp_name->mech_name); + if (union_exp_name->mech_type) + generic_gss_release_oid(&tmp, &union_exp_name->mech_type); + free(union_exp_name); + } +return (major_status); + +} + diff -puN /dev/null support/gssapi/gen_oids.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/gen_oids.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,80 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mglueP.h" + +/* + * See krb5/gssapi_krb5.c for a description of the algorithm for + * encoding an object identifier. + */ + +/* + * The OID of user_name is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) user_name(1) = 1.2.840.113554.1.2.1.1 + * machine_uid_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) machine_uid_name(2) = 1.2.840.113554.1.2.1.2 + * string_uid_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) string_uid_name(3) = 1.2.840.113554.1.2.1.3 + * service_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4) = 1.2.840.113554.1.2.1.4 + * anonymous_name: + * iso(1) org(3) dod(6) internet(1) security(5) nametypes(6) + * gss-anonymous-name(3) = 1.3.6.1.5.6.3 + * exported_name: + * iso(1) org(3) dod(6) internet(1) security(5) nametypes(6) + * gss-api-exported-name(4) = 1.3.6.1.5.6.4 + * + */ + +static const gss_OID_desc oids[] = { + {10, "\052\206\110\206\367\022\001\002\001\001"}, + {10, "\052\206\110\206\367\022\001\002\001\002"}, + {10, "\052\206\110\206\367\022\001\002\001\003"}, + {10, "\052\206\110\206\367\022\001\002\001\004"}, + {6, "\053\006\001\005\006\003"}, + {6, "\053\006\001\005\006\004"}, +}; + + +/* + * rfc2744 defines the UPPERCASE names, the lowercase names are + * the original MIT names and should not be used in new applications + */ +const gss_OID_desc * const GSS_C_NT_USER_NAME = oids+0; +const gss_OID_desc * const gss_nt_user_name = oids+0; + +const gss_OID_desc * const GSS_C_NT_MACHINE_UID_NAME = oids+1; +const gss_OID_desc * const gss_nt_machine_uid_name = oids+1; + +const gss_OID_desc * const GSS_C_NT_STRING_UID_NAME = oids+2; +const gss_OID_desc * const gss_nt_string_uid_name = oids+2; + +const gss_OID_desc * const GSS_C_NT_HOSTBASED_SERVICE = oids+3; +const gss_OID_desc * const gss_nt_service_name = oids+3; + +const gss_OID_desc * const GSS_C_NT_ANONYMOUS = oids+4; + +const gss_OID_desc * const GSS_C_NT_EXPORT_NAME = oids+5; diff -puN /dev/null support/gssapi/g_exp_sec_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_exp_sec_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,108 @@ +/* #ident "@(#)g_exp_sec_context.c 1.2 96/01/18 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_export_sec_context + */ + +#include "mglueP.h" +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +OM_uint32 KRB5_CALLCONV +gss_export_sec_context(minor_status, + context_handle, + interprocess_token) + +OM_uint32 * minor_status; +gss_ctx_id_t * context_handle; +gss_buffer_t interprocess_token; + +{ + OM_uint32 status; + size_t length; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + gss_buffer_desc token; + char *buf; + + gss_initialize(); + + if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) *context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + if (!mech) + return GSS_S_BAD_MECH; + if (!mech->gss_export_sec_context) + return GSS_S_BAD_BINDINGS; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_export_sec_context(mech->context, minor_status, +#else + status = mech->gss_export_sec_context(minor_status, +#endif + &ctx->internal_ctx_id, &token); + if (status != GSS_S_COMPLETE) + return (status); + + length = token.length + 4 + ctx->mech_type->length; + interprocess_token->length = length; + interprocess_token->value = malloc(length); + if (interprocess_token->value == 0) { + (void) gss_release_buffer(minor_status, &token); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + buf = interprocess_token->value; + length = ctx->mech_type->length; + buf[3] = (unsigned char) (length & 0xFF); + length >>= 8; + buf[2] = (unsigned char) (length & 0xFF); + length >>= 8; + buf[1] = (unsigned char) (length & 0xFF); + length >>= 8; + buf[0] = (unsigned char) (length & 0xFF); + memcpy(buf+4, ctx->mech_type->elements, (size_t) ctx->mech_type->length); + memcpy(buf+4+ctx->mech_type->length, token.value, token.length); + + (void) gss_release_buffer(minor_status, &token); + + free(ctx->mech_type->elements); + free(ctx->mech_type); + free(ctx); + *context_handle = 0; + + return(GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_glue.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_glue.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,344 @@ +/* #ident "@(#)g_glue.c 1.1 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +extern gss_mechanism *__gss_mechs_array; + +/* + * This file contains the support routines for the glue layer. + */ + +/* + * given the mechs_array and a mechanism OID, return the + * pointer to the mechanism, or NULL if that mechanism is + * not supported. If the requested OID is NULL, then return + * the first mechanism. + */ + +gss_mechanism __gss_get_mechanism (type) + gss_OID type; +{ + int i; + + if (type == GSS_C_NULL_OID) + return (__gss_mechs_array[0]); + + for (i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) { + if ((__gss_mechs_array[i]->mech_type.length == type->length) && + (memcmp (__gss_mechs_array[i]->mech_type.elements, type->elements, + type->length) == 0)) { + + return (__gss_mechs_array[i]); + } + } + return NULL; +} + + +/* + * glue routine for get_mech_type + * + */ + +OM_uint32 __gss_get_mech_type(OID, token) + gss_OID OID; + gss_buffer_t token; +{ + unsigned char * buffer_ptr; + int length; + + /* + * This routine reads the prefix of "token" in order to determine + * its mechanism type. It assumes the encoding suggested in + * Appendix B of RFC 1508. This format starts out as follows : + * + * tag for APPLICATION 0, Sequence[constructed, definite length] + * length of remainder of token + * tag of OBJECT IDENTIFIER + * length of mechanism OID + * encoding of mechanism OID + * + * + * Numerically, this looks like : + * + * 0x60 + * - could be multiple bytes + * 0x06 + * - assume only one byte, hence OID length < 127 + * + * + * The routine fills in the OID value and returns an error as necessary. + */ + + if (token == NULL) + return (GSS_S_DEFECTIVE_TOKEN); + + /* Skip past the APP/Sequnce byte and the token length */ + + buffer_ptr = (unsigned char *) token->value; + + if (*(buffer_ptr++) != 0x60) + return (GSS_S_DEFECTIVE_TOKEN); + length = *buffer_ptr++; + if (length & 0x80) { + if ((length & 0x7f) > 4) + return (GSS_S_DEFECTIVE_TOKEN); + buffer_ptr += length & 0x7f; + } + + if (*(buffer_ptr++) != 0x06) + return (GSS_S_DEFECTIVE_TOKEN); + + OID->length = (OM_uint32) *(buffer_ptr++); + OID->elements = (void *) buffer_ptr; + return (GSS_S_COMPLETE); +} + + +/* + * Internal routines to get and release an internal mechanism name + */ + +#include "mglueP.h" + +OM_uint32 __gss_import_internal_name (minor_status, mech_type, union_name, + internal_name) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_union_name_t union_name; +gss_name_t *internal_name; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (mech) { + if (mech->gss_import_name) + status = mech->gss_import_name ( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + union_name->external_name, + union_name->name_type, + internal_name); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + +OM_uint32 __gss_display_internal_name (minor_status, mech_type, internal_name, + external_name, name_type) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_name_t internal_name; +gss_buffer_t external_name; +gss_OID *name_type; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (mech) { + if (mech->gss_display_name) + status = mech->gss_display_name ( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + internal_name, + external_name, + name_type); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + +OM_uint32 __gss_release_internal_name (minor_status, mech_type, internal_name) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_name_t *internal_name; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (mech) { + if (mech->gss_release_name) + status = mech->gss_release_name ( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + internal_name); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + + +/* + * This function converts an internal gssapi name to a union gssapi + * name. Note that internal_name should be considered "consumed" by + * this call, whether or not we return an error. + */ +OM_uint32 __gss_convert_name_to_union_name(minor_status, mech, + internal_name, external_name) + OM_uint32 *minor_status; + gss_mechanism mech; + gss_name_t internal_name; + gss_name_t *external_name; +{ + OM_uint32 major_status,tmp; + gss_union_name_t union_name; + + union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_name->mech_type = 0; + union_name->mech_name = internal_name; + union_name->name_type = 0; + union_name->external_name = 0; + union_name->gss_mech = mech; + + major_status = generic_gss_copy_oid(minor_status, &mech->mech_type, + &union_name->mech_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + union_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + +#ifdef USE_MECH_CONTEXT + major_status = mech->gss_display_name(mech->context, minor_status, +#else + major_status = mech->gss_display_name(minor_status, +#endif + internal_name, + union_name->external_name, + &union_name->name_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + *external_name = union_name; + return (GSS_S_COMPLETE); + +allocation_failure: + if (union_name) { + if (union_name->external_name) { + if (union_name->external_name->value) + free(union_name->external_name->value); + free(union_name->external_name); + } + if (union_name->name_type) + generic_gss_release_oid(&tmp, &union_name->name_type); + if (union_name->mech_name) + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + if (union_name->mech_type) + mech_gss_release_oid(&tmp, &union_name->mech_type, mech); + free(union_name); + } + return (major_status); +} + +/* + * Glue routine for returning the mechanism-specific credential from a + * external union credential. + */ +gss_cred_id_t +__gss_get_mechanism_cred(union_cred, mech_type) + gss_union_cred_t union_cred; + gss_OID mech_type; +{ + int i; + + if (union_cred == GSS_C_NO_CREDENTIAL) + return GSS_C_NO_CREDENTIAL; + + for (i=0; i < union_cred->count; i++) { + if (g_OID_equal(mech_type, &union_cred->mechs_array[i])) + return union_cred->cred_array[i]; + } + return GSS_C_NO_CREDENTIAL; +} + + +/* + * Glue routine to copy an external name buffer (used by gss_duplicate_name) + */ +OM_uint32 __gss_copy_namebuf(src, dest) + gss_buffer_t src; + gss_buffer_t *dest; +{ + gss_buffer_t temp = NULL; + + if (dest == NULL) + return (GSS_S_BAD_NAME); + + temp = (gss_buffer_t) malloc (sizeof(gss_buffer_t)); + if (!temp) { + return(GSS_S_FAILURE); + } + temp->value = (void *) malloc (src->length + 1); + if (temp->value == NULL) { + free(temp); + return(GSS_S_FAILURE); + } + + memcpy(temp->value, src->value, src->length); + temp->length = src->length; + + *dest = temp; + return (GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_imp_name.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_imp_name.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,161 @@ +/* #ident "@(#)g_imp_name.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_import_name + * + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include + +OM_uint32 KRB5_CALLCONV +gss_import_name(minor_status, + input_name_buffer, + input_name_type, + output_name) + +OM_uint32 * minor_status; +gss_buffer_t input_name_buffer; +gss_OID input_name_type; +gss_name_t * output_name; + +{ + gss_union_name_t union_name; + OM_uint32 tmp, major_status = GSS_S_FAILURE; + gss_OID mech; + + gss_initialize(); + + if (minor_status) + *minor_status = 0; + + /* if output_name is NULL, simply return */ + + if(output_name == NULL) + return (GSS_S_COMPLETE); + + *output_name = 0; + + if (input_name_buffer == GSS_C_NO_BUFFER) + return (GSS_S_BAD_NAME); + + /* + * First create the union name struct that will hold the external + * name and the name type. + */ + + union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_name->mech_type = 0; + union_name->mech_name = 0; + union_name->name_type = 0; + union_name->external_name = 0; + union_name->gss_mech = NULL; + + /* + * All we do here is record the external name and name_type. + * When the name is actually used, the underlying gss_import_name() + * is called for the appropriate mechanism. Note that the name type + * is assumed to be constant, so only a pointer to it is stored in + * union_name + */ + union_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + + union_name->external_name->length = input_name_buffer->length; + /* we malloc length+1 to stick a NULL on the end, just in case */ + /* Note that this NULL is not included in ->length for a reason! */ + union_name->external_name->value = + (void *) malloc(input_name_buffer->length+1); + if (!union_name->external_name->value) { + *minor_status = ENOMEM; + goto allocation_failure; + } + + memcpy(union_name->external_name->value, input_name_buffer->value, + input_name_buffer->length); + + /* add NULL to end of external_name->value, just in case... */ + ((char *)union_name->external_name->value) + [input_name_buffer->length] = '\0'; + + major_status = generic_gss_copy_oid(minor_status, input_name_type, + &union_name->name_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + /* + * See if this is a mechanism-specific name. If so, let's import + * it now so we can get any error messages, and to avoid trouble + * later... + */ + mech = gss_find_mechanism_from_name_type(input_name_type); + if (mech) { + major_status = generic_gss_copy_oid(minor_status, mech, + &union_name->mech_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + major_status = __gss_import_internal_name(minor_status, mech, + union_name, + &union_name->mech_name); + if (major_status) + goto allocation_failure; + } + + *output_name = (gss_name_t) union_name; + + return(GSS_S_COMPLETE); + +allocation_failure: + if (union_name) { + if (union_name->external_name) { + if (union_name->external_name->value) + free(union_name->external_name->value); + free(union_name->external_name); + } + if (union_name->name_type) + generic_gss_release_oid(&tmp, &union_name->name_type); + if (union_name->mech_name) + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + if (union_name->mech_type) + generic_gss_release_oid(&tmp, &union_name->mech_type); + free(union_name); + } + return (major_status); +} diff -puN /dev/null support/gssapi/g_imp_sec_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_imp_sec_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,128 @@ +/* #ident "@(#)g_imp_sec_context.c 1.2 96/01/18 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_export_sec_context + */ + +#include "mglueP.h" +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +OM_uint32 KRB5_CALLCONV +gss_import_sec_context(minor_status, + interprocess_token, + context_handle) + +OM_uint32 * minor_status; +gss_buffer_t interprocess_token; +gss_ctx_id_t * context_handle; + +{ + size_t length; + OM_uint32 status; + char *p; + gss_union_ctx_id_t ctx; + gss_buffer_desc token; + gss_mechanism mech; + + gss_initialize(); + + *minor_status = 0; + + if (interprocess_token->length == 0 || interprocess_token->value == 0) + return (GSS_S_DEFECTIVE_TOKEN); + + status = GSS_S_FAILURE; + + ctx = (gss_union_ctx_id_t) malloc(sizeof(gss_union_ctx_id_desc)); + if (!ctx) { + *minor_status = ENOMEM; + goto error_out; + } + ctx->mech_type = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!ctx->mech_type) { + *minor_status = ENOMEM; + goto error_out; + } + p = interprocess_token->value; + length = *p++; + length = (length << 8) + *p++; + length = (length << 8) + *p++; + length = (length << 8) + *p++; + + ctx->mech_type->length = length; + ctx->mech_type->elements = malloc(length); + if (!ctx->mech_type->elements) { + *minor_status = ENOMEM; + goto error_out; + } + memcpy(ctx->mech_type->elements, p, length); + p += length; + + token.length = interprocess_token->length - 4 - length; + token.value = p; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (ctx->mech_type); + if (!mech) { + status = GSS_S_BAD_MECH; + goto error_out; + } + if (!mech->gss_import_sec_context) { + status = GSS_S_BAD_BINDINGS; + goto error_out; + } + +#ifdef USE_MECH_CONTEXT + status = mech->gss_import_sec_context(mech->context, minor_status, +#else + status = mech->gss_import_sec_context(minor_status, +#endif + &token, &ctx->internal_ctx_id); + + if (status == GSS_S_COMPLETE) { + *context_handle = ctx; + return (GSS_S_COMPLETE); + } + +error_out: + if (ctx) { + if (ctx->mech_type) { + if (ctx->mech_type->elements) + free(ctx->mech_type->elements); + free(ctx->mech_type); + } + free(ctx); + } + return status; +} diff -puN /dev/null support/gssapi/g_indicate_mechs.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_indicate_mechs.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,90 @@ +/* #ident "@(#)gss_indicate_mechs.c 1.13 95/08/04 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_indicate_mechs + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +extern gss_mechanism *__gss_mechs_array; + +static gss_OID_set_desc supported_mechs_desc; +static gss_OID_set supported_mechs = NULL; + +OM_uint32 KRB5_CALLCONV +gss_indicate_mechs (minor_status, + mech_set) + +OM_uint32 * minor_status; +gss_OID_set * mech_set; + +{ + int i; + + gss_initialize(); + + if (minor_status) + *minor_status = 0; + + /* + * If we have already computed the mechanisms supported, return + * a pointer to it. Otherwise, compute them and return the pointer. + */ + + if(supported_mechs == NULL) { + + supported_mechs = &supported_mechs_desc; + supported_mechs->count = 0; + + /* Build the mech_set from the OIDs in mechs_array. */ + + for(i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) + supported_mechs->count++; + + supported_mechs->elements = + (void *) malloc(supported_mechs->count * + sizeof(gss_OID_desc)); + + for(i=0; i < supported_mechs->count; i++) { + supported_mechs->elements[i].length = + __gss_mechs_array[i]->mech_type.length; + supported_mechs->elements[i].elements = (void *) + malloc(__gss_mechs_array[i]->mech_type.length); + memcpy(supported_mechs->elements[i].elements, + __gss_mechs_array[i]->mech_type.elements, + __gss_mechs_array[i]->mech_type.length); + } + } + + if(mech_set != NULL) + *mech_set = supported_mechs; + + return(GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_initialize.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_initialize.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,380 @@ +/* #ident "@(#)g_initialize.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This function will initialize the gssapi mechglue library + */ + +#include "config.h" +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +#include +#include +#include +#include + +#ifdef USE_SOLARIS_SHARED_LIBRARIES +#include + +#define MECH_CONF "/etc/mech.conf" +#define MECH_SYM "gss_mech_initialize" + +static void solaris_initialize (void); +#endif /* USE_SOLARIS_SHARED_LIBRARIES */ + +#ifdef __linux__ +#define USE_LINUX_SHARED_LIBRARIES +#endif + +#ifdef USE_LINUX_SHARED_LIBRARIES +#include +#define MECH_CONF "/etc/gssapi_mech.conf" +#define MECH_SYM "gss_mech_initialize" +static void linux_initialize (void); +#endif /* USE_LINUX_SHARED_LIBRARIES */ + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +extern gss_mechanism krb5_gss_initialize(); + +static int _gss_initialized = 0; + +static struct gss_config null_mech = { + {0,NULL}}; + +gss_mechanism *__gss_mechs_array = NULL; + +/* + * This function will add a new mechanism to the mechs_array + */ + +static OM_uint32 +add_mechanism (mech, replace) + gss_mechanism mech; + int replace; +{ + gss_mechanism * temp_array; + gss_OID_set mech_names; + OM_uint32 minor_status, major_status; + unsigned int i; + + if (mech == NULL) + return GSS_S_COMPLETE; + + /* initialize the mechs_array if it hasn't already been initialized */ + if (__gss_mechs_array == NULL) { + __gss_mechs_array = (gss_mechanism *) malloc (sizeof(gss_mechanism)); + + if (__gss_mechs_array == NULL) + return ENOMEM; + + __gss_mechs_array[0] = &null_mech; + } + + /* + * Find the length of __gss_mechs_array, and look for an existing + * entry for this OID + */ + for (i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) { + if (!g_OID_equal(&__gss_mechs_array[i]->mech_type, + &mech->mech_type)) + continue; + + /* We found a match. Replace it? */ + if (!replace) + return GSS_S_FAILURE; + + __gss_mechs_array[i] = mech; + return GSS_S_COMPLETE; + } + + /* we didn't find it -- add it to the end of the __gss_mechs_array */ + temp_array = (gss_mechanism *) realloc(__gss_mechs_array, + (i+2)*sizeof(gss_mechanism)); + + if (temp_array == NULL) + return ENOMEM; + + temp_array[i++] = mech; + temp_array[i] = &null_mech; + + __gss_mechs_array = temp_array; + + /* + * OK, now let's register all of the name types this mechanism + * knows how to deal with. + */ + major_status = gss_inquire_names_for_mech(&minor_status, &mech->mech_type, + &mech_names); + if (major_status != GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + for (i=0; i < mech_names->count; i++) { + gss_add_mech_name_type(&minor_status, &mech_names->elements[i], + &mech->mech_type); + } + (void) gss_release_oid_set(&minor_status, &mech_names); + + return GSS_S_COMPLETE; +} + +void gss_initialize () +{ + /* Make sure we've not run already */ + if (_gss_initialized) + return; + _gss_initialized = 1; + +#ifdef USE_SOLARIS_SHARED_LIBRARIES + solaris_initialize(); + +#elif defined(USE_LINUX_SHARED_LIBRARIES) + linux_initialize(); + +#else + { + gss_mechanism mech; + + /* + * Use hard-coded in mechanisms... I need to know what mechanisms + * are supported... As more mechanisms become supported, they + * should be added here, unless shared libraries are used. + */ + + /* Initialize the krb5 mechanism */ + mech = (gss_mechanism)krb5_gss_initialize(); + if (mech) + add_mechanism (mech, 1); + } + +#endif /* USE_SOLARIS_SHARED_LIBRARIES */ + +#if !defined(macintosh) + if (__gss_mechs_array == NULL) { /* this is very bad! */ + fprintf(stderr,"gss_initialize fatal error: no mechanisms loaded!\n"); + exit(-1); + } +#else + /* + * Nothing for now, since this should never happen using static + * mechanism loading. + */ +#endif + + return; +} + +#ifdef USE_SOLARIS_SHARED_LIBRARIES +/* + * read the configuration file to find out what mechanisms to + * load, load them, and then load the mechanism defitions in + * and add the mechanisms + */ +static void solaris_initialize () +{ + char buffer[BUFSIZ], *filename, *symname, *endp; + FILE *conffile; + void *dl; + gss_mechanism (*sym)(void), mech; + + if ((filename = getenv("GSSAPI_MECH_CONF")) == NULL) + filename = MECH_CONF; + + if ((conffile = fopen(filename, "r")) == NULL) { + fprintf(stderr,"fatal error: unable to open %s:" + " errno %d (%s)\n", filename, errno, strerror(errno)); + return; + } + + while (fgets (buffer, BUFSIZ, conffile) != NULL) { + /* ignore lines beginning with # */ + if (*buffer == '#') + continue; + + /* find the first white-space character after the filename */ + for (symname = buffer; *symname && !isspace(*symname); symname++); + + /* Now find the first non-white-space character */ + if (*symname) { + *symname = '\0'; + symname++; + while (*symname && isspace(*symname)) + symname++; + } + + if (! *symname) + symname = MECH_SYM; + else { + /* Find the end of the symname and make sure it is NULL-terminated */ + for (endp = symname; *endp && !isspace(*endp); endp++); + if (*endp) + *endp = '\0'; + } + + if ((dl = dlopen(buffer, RTLD_NOW)) == NULL) { + /* for debugging only */ + fprintf(stderr,"can't open %s: %s\n",buffer, dlerror()); + continue; + } + + if ((sym = (gss_mechanism (*)(void))dlsym(dl, symname)) == NULL) { + dlclose(dl); + continue; + } + + /* Call the symbol to get the mechanism table */ + mech = sym(); + + /* And add the mechanism (or close the shared library) */ + if (mech) + add_mechanism (mech, 1); + else + dlclose(dl); + + } /* while */ + + return; +} +#endif /* USE_SOLARIS_SHARED_LIBRARIES */ + +#ifdef USE_LINUX_SHARED_LIBRARIES +extern gss_mechanism internal_krb5_gss_initialize(void *dl); + +/* + * read the configuration file to find out what mechanisms to + * load, load them, and then load the mechanism defitions in + * and add the mechanisms + */ +static void linux_initialize () +{ + char buffer[BUFSIZ], *filename, *symname, *endp, *err_string; + FILE *conffile; + void *dl; + gss_mechanism (*sym)(void), mech; + + if ((filename = getenv("GSSAPI_MECH_CONF")) == NULL) + filename = MECH_CONF; + + if ((conffile = fopen(filename, "r")) == NULL) { + fprintf(stderr,"fatal error: unable to open %s:" + " errno %d (%s)\n", filename, errno, strerror(errno)); + return; + } + + while (fgets (buffer, BUFSIZ, conffile) != NULL) { + /* ignore lines beginning with # */ + if (*buffer == '#') + continue; + + /* find the first white-space character after the filename */ + for (symname = buffer; *symname && !isspace(*symname); symname++); + + /* Now find the first non-white-space character */ + if (*symname) { + *symname = '\0'; + symname++; + while (*symname && isspace(*symname)) + symname++; + } + + if (! *symname) + symname = MECH_SYM; + else { + /* Find the end of the symname and make sure it is + * NULL-terminated */ + for (endp = symname; *endp && !isspace(*endp); endp++); + if (*endp) + *endp = '\0'; + } + + if ((dl = dlopen(buffer, RTLD_NOW)) == NULL) { + /* for debugging only */ + fprintf(stderr,"can't open %s: %s\n",buffer, dlerror()); + continue; + } + +#if defined(HAVE_KRB5) && defined(HAVE_HEIMDAL) +#error Should not have both HAVE_KRB5 and HAVE_HEIMDAL defined!! +#endif + +#ifdef HAVE_KRB5 + /* Special case for dealing with MIT krb5 mechanism */ + if (strcmp(symname, "mechglue_internal_krb5_init") == 0) { +#ifdef DEBUG + fprintf(stderr, "Using special MIT initialization\n"); +#endif + mech = internal_krb5_gss_initialize(dl); + } + else +#endif + +#ifdef HAVE_HEIMDAL + /* Special case for dealing with heimdal krb5 mechanism */ + if (strcmp(symname, "mechglue_internal_heimdal_init") == 0) { +#ifdef DEBUG + fprintf(stderr, "Using special Heimdal initialization\n"); +#endif + mech = internal_heimdal_gss_initialize(dl); + } + else +#endif + { + if ((sym = (gss_mechanism (*)(void))dlsym(dl, symname)) == NULL) { + if ((err_string = dlerror()) != NULL) { + fprintf(stderr, "%s: searching for symbol '%s' in '%s'\n", + err_string, symname, buffer); + dlclose(dl); + } + continue; + } + + /* Call the symbol to get the mechanism table */ + mech = sym(); + } + + /* And add the mechanism (or close the shared library) */ + if (mech) { +#ifdef DEBUG + fprintf(stderr, "Adding mechanism for library '%s'\n", buffer); +#endif + add_mechanism (mech, 1); + } + else { +#ifdef DEBUG + fprintf(stderr, + "Failed to initialize mechanism for library '%s'\n", + buffer); +#endif + dlclose(dl); + } + + } /* while */ + + return; +} +#endif /* USE_LINUX_SHARED_LIBRARIES */ diff -puN /dev/null support/gssapi/g_init_sec_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_init_sec_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,194 @@ +/* #ident "@(#)gss_init_sec_context.c 1.20 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_init_sec_context + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +OM_uint32 KRB5_CALLCONV +gss_init_sec_context (minor_status, + claimant_cred_handle, + context_handle, + target_name, + req_mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec) + +OM_uint32 * minor_status; +gss_cred_id_t claimant_cred_handle; +gss_ctx_id_t * context_handle; +gss_name_t target_name; +gss_OID req_mech_type; +OM_uint32 req_flags; +OM_uint32 time_req; +gss_channel_bindings_t input_chan_bindings; +gss_buffer_t input_token; +gss_OID * actual_mech_type; +gss_buffer_t output_token; +OM_uint32 * ret_flags; +OM_uint32 * time_rec; + +{ + OM_uint32 status, temp_status, temp_minor_status; + gss_union_name_t union_name; + gss_union_cred_t union_cred; + gss_name_t internal_name; + gss_union_ctx_id_t union_ctx_id; + gss_OID mech_type = (gss_OID) req_mech_type; + gss_mechanism mech; + gss_cred_id_t input_cred_handle; + + gss_initialize(); + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + union_name = (gss_union_name_t) target_name; + + /* + * If mech_type is NULL, and the target_name is + * mechanism-specific, then set it to the mech_type of + * target_name. + */ + if ((mech_type == GSS_C_NULL_OID) && union_name->mech_type) + mech_type = union_name->mech_type; + + /* + * obtain the gss mechanism information for the requested + * mechanism. If mech_type is NULL, set it to the resultant + * mechanism + */ + mech = __gss_get_mechanism (mech_type); + if (mech == NULL) + return (GSS_S_BAD_MECH); + + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + /* + * If target_name is mechanism_specific, then it must match the + * mech_type that we're about to use. Otherwise, do an import on + * the external_name form of the target name. + */ + if (union_name->mech_type) { + if (!g_OID_equal(union_name->mech_type, mech_type)) + return (GSS_S_BAD_MECH); + internal_name = union_name->mech_name; + } else { + if ((temp_status = __gss_import_internal_name(minor_status, mech_type, + union_name, + &internal_name))) + return (GSS_S_BAD_NAME); + } + + /* + * if context_handle is GSS_C_NO_CONTEXT, allocate a union context + * descriptor to hold the mech type information as well as the + * underlying mechanism context handle. Otherwise, cast the + * value of *context_handle to the union context variable. + */ + + if(*context_handle == GSS_C_NO_CONTEXT) { + union_ctx_id = (gss_union_ctx_id_t) + malloc(sizeof(gss_union_ctx_id_desc)); + + union_ctx_id->mech_type = (gss_OID) + malloc(sizeof(gss_OID_desc)); + + /* copy in the mech type information */ + + union_ctx_id->mech_type->elements = (void *) + malloc(mech_type->length); + + union_ctx_id->mech_type->length = mech_type->length; + memcpy(union_ctx_id->mech_type->elements, mech_type->elements, + mech_type->length); + + /* copy the supplied context handle */ + + union_ctx_id->internal_ctx_id = *context_handle; + } else + union_ctx_id = *context_handle; + + /* + * get the appropriate cred handle from the union cred struct. + * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will + * use the default credential. + */ + union_cred = (gss_union_cred_t) claimant_cred_handle; + input_cred_handle = __gss_get_mechanism_cred(union_cred, mech_type); + + /* + * now call the approprate underlying mechanism routine + */ + + if (mech->gss_init_sec_context) { + status = mech->gss_init_sec_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + input_cred_handle, + &union_ctx_id->internal_ctx_id, + internal_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + + if (*context_handle == GSS_C_NO_CONTEXT) + *context_handle = (gss_ctx_id_t) union_ctx_id; + + } else + status = GSS_S_BAD_BINDINGS; + + if (!union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + mech_type, &internal_name); + } + + return(status); +} diff -puN /dev/null support/gssapi/g_inq_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_inq_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,143 @@ +/* #ident "@(#)g_inquire_context.c 1.2 96/01/18 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_inquire_context + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +/* Last argument new for V2 */ +OM_uint32 KRB5_CALLCONV +gss_inquire_context( + minor_status, + context_handle, + src_name, + targ_name, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_name_t * src_name; +gss_name_t * targ_name; +OM_uint32 * lifetime_rec; +gss_OID * mech_type; +OM_uint32 * ctx_flags; +int * locally_initiated; +int * open; + + +{ + gss_union_ctx_id_t ctx; + gss_mechanism mech; + OM_uint32 status, temp_minor; + + gss_initialize(); + + /* if the context_handle is Null, return NO_CONTEXT error */ + + if(context_handle == GSS_C_NO_CONTEXT) + return(GSS_S_NO_CONTEXT); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (!mech || !mech->gss_inquire_context || !mech->gss_display_name) { + return(GSS_S_NO_CONTEXT); + + } + + status = mech->gss_inquire_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + src_name, + targ_name, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open); + + if (status != GSS_S_COMPLETE) { + return status; + } + + /* need to convert names */ + + if (src_name) { + status = __gss_convert_name_to_union_name(minor_status, mech, + *src_name, src_name); + + if (status != GSS_S_COMPLETE) { +#ifdef USE_MECH_CONTEXT + (void) mech->gss_release_name(mech->context, +#else + (void) mech->gss_release_name( +#endif + &temp_minor, src_name); +#ifdef USE_MECH_CONTEXT + (void) mech->gss_release_name(mech->context, +#else + (void) mech->gss_release_name( +#endif + &temp_minor, targ_name); + if (mech_type) { + mech_gss_release_oid(&temp_minor, mech_type, + mech); + } + return (GSS_S_FAILURE); + } + + } + + if (targ_name) { + status = __gss_convert_name_to_union_name(minor_status, mech, + *targ_name, targ_name); + + if (status != GSS_S_COMPLETE) { + if (mech_type) { + mech_gss_release_oid(&temp_minor, mech_type, mech); + } + return (GSS_S_FAILURE); + } + } + + return(GSS_S_COMPLETE); +} + diff -puN /dev/null support/gssapi/g_inq_cred.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_inq_cred.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,199 @@ +/* #ident "@(#)gss_inquire_cred.c 1.9 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_inquire_cred + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include + +OM_uint32 KRB5_CALLCONV +gss_inquire_cred(minor_status, + cred_handle, + name, + lifetime, + cred_usage, + mechanisms) + +OM_uint32 * minor_status; +gss_cred_id_t cred_handle; +gss_name_t * name; +OM_uint32 * lifetime; +int * cred_usage; +gss_OID_set * mechanisms; + +{ + OM_uint32 status, elapsed_time, temp_minor_status; + gss_union_cred_t union_cred; + gss_mechanism mech; + gss_name_t internal_name; + int i; + + gss_initialize(); + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + /* + * No credential was supplied. This means we can't get a mechanism + * pointer to call the mechanism specific gss_inquire_cred. + * So, call get_mechanism with an arguement of GSS_C_NULL_OID. + * get_mechanism will return the first mechanism in the mech + * array, which becomes the default mechanism. + */ + + if ((mech = __gss_get_mechanism(GSS_C_NULL_OID)) == NULL) + return(GSS_S_NO_CRED); + + if (!mech->gss_inquire_cred) + return (GSS_S_FAILURE); + +#ifdef USE_MECH_CONTEXT + status = mech->gss_inquire_cred(mech->context, minor_status, +#else + status = mech->gss_inquire_cred(minor_status, +#endif + GSS_C_NO_CREDENTIAL, + name ? &internal_name : NULL, + lifetime, cred_usage, mechanisms); + + if (status != GSS_S_COMPLETE) + return(status); + + if (name) { + /* + * Convert internal_name into a union_name equivalent. + */ + status = __gss_convert_name_to_union_name(&temp_minor_status, + mech, internal_name, + name); + if (status != GSS_S_COMPLETE) { + if (minor_status) + *minor_status = temp_minor_status; + __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, &internal_name); + return (status); + } + } + return(GSS_S_COMPLETE); + } + + /* get the cred_handle cast as a union_credentials structure */ + + union_cred = (gss_union_cred_t) cred_handle; + + /* + * get the information out of the union_cred structure that was + * placed there during gss_acquire_cred. + */ + + if(cred_usage != NULL) + *cred_usage = union_cred->auxinfo.cred_usage; + + if(lifetime != NULL) { + elapsed_time = time(0) - union_cred->auxinfo.creation_time; + *lifetime = union_cred->auxinfo.time_rec < elapsed_time ? 0 : + union_cred->auxinfo.time_rec - elapsed_time; + } + + /* + * if name is non_null, + * call gss_import_name(), giving it the printable name held within + * union_cred in order to get an internal name to pass back to the + * caller. If this call fails, return failure to our caller. + */ + + if(name != NULL) + if(gss_import_name(&temp_minor_status, + &union_cred->auxinfo.name, + union_cred->auxinfo.name_type, + name) != GSS_S_COMPLETE) + return(GSS_S_DEFECTIVE_CREDENTIAL); + + /* + * copy the mechanism set in union_cred into an OID set and return in + * the mechanisms parameter. + */ + + if(mechanisms != NULL) { + + *mechanisms = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)); + + (*mechanisms)->count = union_cred->count; + (*mechanisms)->elements = + (gss_OID) malloc(sizeof(gss_OID_desc) * + union_cred->count); + + for(i=0; i < union_cred->count; i++) { + (*mechanisms)->elements[i].length = + union_cred->mechs_array[i].length; + (*mechanisms)->elements[i].elements = (void *) + malloc(union_cred->mechs_array[i].length); + memcpy((*mechanisms)->elements[i].elements, + union_cred->mechs_array[i].elements, + union_cred->mechs_array[i].length); + } + } + + return(GSS_S_COMPLETE); +} + +OM_uint32 KRB5_CALLCONV +gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, + initiator_lifetime, acceptor_lifetime, cred_usage) + OM_uint32 *minor_status; + gss_cred_id_t cred_handle; + gss_OID mech_type; + gss_name_t *name; + OM_uint32 *initiator_lifetime; + OM_uint32 *acceptor_lifetime; + gss_cred_usage_t *cred_usage; +{ + gss_union_cred_t union_cred; + gss_cred_id_t mech_cred; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_inquire_cred_by_mech) + return (GSS_S_BAD_BINDINGS); + + union_cred = (gss_union_cred_t) cred_handle; + mech_cred = __gss_get_mechanism_cred(union_cred, mech_type); + +#ifdef USE_MECH_CONTEXT + return (mech->gss_inquire_cred_by_mech(mech->context, minor_status, +#else + return (mech->gss_inquire_cred_by_mech(minor_status, +#endif + mech_cred, mech_type, + name, initiator_lifetime, + acceptor_lifetime, cred_usage)); +} + diff -puN /dev/null support/gssapi/g_inq_names.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_inq_names.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,69 @@ +/* #ident "@(#)g_inquire_names.c 1.1 95/12/19 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_inquire_context + */ + +#include "mglueP.h" + +/* Last argument new for V2 */ +OM_uint32 KRB5_CALLCONV +gss_inquire_names_for_mech(minor_status, mechanism, name_types) + +OM_uint32 * minor_status; +gss_OID mechanism; +gss_OID_set * name_types; + +{ + OM_uint32 status; + gss_mechanism mech; + + gss_initialize(); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (mechanism); + + if (mech) { + + if (mech->gss_inquire_names_for_mech) + status = mech->gss_inquire_names_for_mech( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + mechanism, + name_types); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff -puN /dev/null support/gssapi/g_mechname.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_mechname.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,116 @@ +/* + * g_mechname.c --- registry of mechanism-specific name types + * + * This file contains a registry of mechanism-specific name types. It + * is used to determine which name types not should be lazy evaluated, + * but rather evaluated on the spot. + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include +#endif + +#include +#include +#include + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +static gss_mech_spec_name name_list = NULL; + +/* + * generic searching helper function. + */ +static gss_mech_spec_name search_mech_spec(name_type) + gss_OID name_type; +{ + gss_mech_spec_name p; + + for (p = name_list; p; p = p->next) { + if (g_OID_equal(name_type, p->name_type)) + return p; + } + return NULL; +} + +/* + * Given a name_type, if it is specific to a mechanism, return the + * mechanism OID. Otherwise, return NULL. + */ +gss_OID gss_find_mechanism_from_name_type(name_type) + gss_OID name_type; +{ + gss_mech_spec_name p; + + p = search_mech_spec(name_type); + if (!p) + return NULL; + return p->mech; +} + +/* + * This function adds a (name_type, mechanism) pair to the + * mechanism-specific name type registry. If an entry for the + * name_type already exists, then zero out the mechanism entry. + * Otherwise, enter the pair into the registry. + */ +OM_uint32 +gss_add_mech_name_type(minor_status, name_type, mech) + OM_uint32 *minor_status; + gss_OID name_type; + gss_OID mech; +{ + OM_uint32 major_status, tmp; + gss_mech_spec_name p; + + p = search_mech_spec(name_type); + if (p) { + /* + * We found an entry for this name type; mark it as not being + * a mechanism-specific name type. + */ + if (p->mech) { + if (!g_OID_equal(mech, p->mech)) { + generic_gss_release_oid(minor_status, &p->mech); + p->mech = 0; + } + } + return GSS_S_COMPLETE; + } + p = malloc(sizeof(gss_mech_spec_name_desc)); + if (!p) { + *minor_status = ENOMEM; + goto allocation_failure; + } + p->name_type = 0; + p->mech = 0; + + major_status = generic_gss_copy_oid(minor_status, name_type, + &p->name_type); + if (major_status) + goto allocation_failure; + major_status = generic_gss_copy_oid(minor_status, mech, + &p->mech); + if (major_status) + goto allocation_failure; + + p->next = name_list; + p->prev = 0; + name_list = p; + + return GSS_S_COMPLETE; + +allocation_failure: + if (p) { + if (p->mech) + generic_gss_release_oid(&tmp, &p->mech); + if (p->name_type) + generic_gss_release_oid(&tmp, &p->name_type); + free(p); + } + return GSS_S_FAILURE; +} + diff -puN /dev/null support/gssapi/g_mit_krb5_mech.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_mit_krb5_mech.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,297 @@ +/* + * g_mit_krb5_mech.c + * + * Copyright (c) 2004 The Regents of the University of Michigan. + * All rights reserved. + * + * Kevin Coffman + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" +#include +#include +#include "mglueP.h" + +/* + * Table of function names that we need to locate within a mechanism's + * shared library if it does not support the xxx_gss_initialize function. + */ +static char *glue_func_names[] = { + "gss_acquire_cred", + "gss_release_cred", + "gss_init_sec_context", + "gss_accept_sec_context", + "gss_process_context_token", + "gss_delete_sec_context", + "gss_context_time", + "gss_sign", + "gss_verify", + "gss_seal", + "gss_unseal", + "gss_display_status", + "gss_indicate_mechs", + "gss_compare_name", + "gss_display_name", + "gss_import_name", + "gss_release_name", + "gss_inquire_cred", + "gss_add_cred", + "gss_export_sec_context", + "gss_import_sec_context", + "gss_inquire_cred_by_mech", + "gss_inquire_names_for_mech", + "gss_inquire_context", + "gss_internal_release_oid", + "gss_wrap_size_limit", + "pname_to_uid", + "gss_duplicate_name", + "gss_set_allowable_enctypes", + "gss_verify_mic", + NULL +}; + +#ifdef HAVE_KRB5 +/* + * The MIT code does not support the krb5_gss_initialize function, so + * we need to locate the functions within the gssapi_krb5.so library + * and fill in this structure. + */ +static struct gss_config mit_krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + NULL, /* mechanism context -- we don't currently use this */ + NULL, /* gss_acquire_cred */ + NULL, /* gss_release_cred */ + NULL, /* gss_init_sec_context */ + NULL, /* gss_accept_sec_context */ + NULL, /* gss_process_context_token */ + NULL, /* gss_delete_sec_context */ + NULL, /* gss_context_time */ + NULL, /* gss_sign */ + NULL, /* gss_verify */ + NULL, /* gss_seal */ + NULL, /* gss_unseal */ + NULL, /* gss_display_status */ + NULL, /* gss_indicate_mechs */ + NULL, /* gss_compare_name */ + NULL, /* gss_display_name */ + NULL, /* gss_import_name */ + NULL, /* gss_release_name */ + NULL, /* gss_inquire_cred */ + NULL, /* gss_add_cred */ + NULL, /* gss_export_sec_context */ + NULL, /* gss_import_sec_context */ + NULL, /* gss_inquire_cred_by_mech */ + NULL, /* gss_inquire_names_for_mech */ + NULL, /* gss_inquire_context */ + NULL, /* gss_internal_release_oid */ + NULL, /* gss_wrap_size_limit */ + NULL, /* pname_to_uid */ + NULL, /* gss_duplicate_name */ + NULL, /* gss_set_allowable_enctypes */ + NULL, /* gss_verify_mic */ +}; +#endif + +#ifdef HAVE_HEIMDAL +/* + * The heimdal code does not support the krb5_gss_initialize function, so + * we need to locate the functions within the libgssapi.so library + * and fill in this structure. + */ +static struct gss_config heimdal_krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + NULL, /* mechanism context -- we don't currently use this */ + NULL, /* gss_acquire_cred */ + NULL, /* gss_release_cred */ + NULL, /* gss_init_sec_context */ + NULL, /* gss_accept_sec_context */ + NULL, /* gss_process_context_token */ + NULL, /* gss_delete_sec_context */ + NULL, /* gss_context_time */ + NULL, /* gss_sign */ + NULL, /* gss_verify */ + NULL, /* gss_seal */ + NULL, /* gss_unseal */ + NULL, /* gss_display_status */ + NULL, /* gss_indicate_mechs */ + NULL, /* gss_compare_name */ + NULL, /* gss_display_name */ + NULL, /* gss_import_name */ + NULL, /* gss_release_name */ + NULL, /* gss_inquire_cred */ + NULL, /* gss_add_cred */ + NULL, /* gss_export_sec_context */ + NULL, /* gss_import_sec_context */ + NULL, /* gss_inquire_cred_by_mech */ + NULL, /* gss_inquire_names_for_mech */ + NULL, /* gss_inquire_context */ + NULL, /* gss_internal_release_oid */ + NULL, /* gss_wrap_size_limit */ + NULL, /* pname_to_uid */ + NULL, /* gss_duplicate_name */ + NULL, /* gss_set_allowable_enctypes */ + NULL, /* gss_verify_mic */ +}; +#endif + + +/* + * Given a handle to a dynamic library (dl) and a symbol + * name (symname), return its address. Returns -1 if the + * symbol cannot be located. (Note that the value of the + * symbol could be NULL, which is valid.) + */ +void * +locate_symbol(void *dl, char *symname, char *prefix) +{ + void *sym; + const char *err_string; + char fullname[256]; + + snprintf(fullname, sizeof(fullname), "%s%s", prefix, symname); + + if ((sym = dlsym(dl, fullname)) == NULL) { + if ((sym = dlsym(dl, symname)) == NULL) { + if ((err_string = dlerror()) != NULL) { + return (void *)-1; + } + else { + return NULL; + } + } + } + return sym; +} + +#ifdef HAVE_KRB5 +/* + * Locate all the symbols in the MIT gssapi library and + * fill in the gss_config (gss_mechanism) structure. + */ +gss_mechanism +internal_krb5_gss_initialize(void *dl) +{ + char *fname; + void *p; + void **fptr; + int i; + static int mit_krb5_initialized = 0; + + if (mit_krb5_initialized) + return (&mit_krb5_mechanism); + + fptr = (void *) &mit_krb5_mechanism.gss_acquire_cred; + + + for (i = 0, fname = glue_func_names[i]; + fname; + i++, fname = glue_func_names[i]) { + if ((p = locate_symbol(dl, fname, "krb5_")) != (void *)-1) { + *fptr++ = p; + } + else { + *fptr++ = NULL; + } + } + if (mit_krb5_mechanism.gss_internal_release_oid == NULL || + mit_krb5_mechanism.gss_internal_release_oid == (void *) -1) { + fprintf(stderr, "WARNING: unable to locate function " + "krb5_gss_internal_release_oid in krb5 mechanism library: " + "there will be problems if multiple mechanisms are used!\n"); + p = locate_symbol(dl, "krb5_gss_release_oid", ""); + if (p == NULL || p == (void *) -1) { + fprintf(stderr, "ERROR: Unable to locate function " + "krb5_gss_internal_release_oid or " + "krb5_gss_release_oid in krb5 mechanism library\n"); + return NULL; + } + } +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES + /* + * Special case for set_allowable_enctypes which has a different + * name format than the rest of the gss routines :-/ + */ + if ((p = locate_symbol(dl, "gss_krb5_set_allowable_enctypes", "")) + != (void *)-1) { + mit_krb5_mechanism.gss_set_allowable_enctypes = p; + } +#endif + mit_krb5_initialized = 1; + return (&mit_krb5_mechanism); +} +#endif + +#ifdef HAVE_HEIMDAL +/* + * Locate all the symbols in the MIT gssapi library and + * fill in the gss_config (gss_mechanism) structure. + */ +gss_mechanism +internal_heimdal_gss_initialize(void *dl) +{ + char *fname; + void *p; + void **fptr; + int i; + static int heimdal_krb5_initialized = 0; + + if (heimdal_krb5_initialized) + return (&heimdal_krb5_mechanism); + + fptr = (void *) &heimdal_krb5_mechanism.gss_acquire_cred; + + + for (i = 0, fname = glue_func_names[i]; + fname; + i++, fname = glue_func_names[i]) { + if ((p = locate_symbol(dl, fname, "")) != (void *)-1) { + *fptr++ = p; + } + else { +printf("Failed to locate function '%s' !!!\n", fname); + *fptr++ = NULL; + } + } + if (heimdal_krb5_mechanism.gss_internal_release_oid == NULL || + heimdal_krb5_mechanism.gss_internal_release_oid == (void *) -1) { + fprintf(stderr, "WARNING: unable to locate function " + "gss_internal_release_oid in krb5 mechanism library: " + "there will be problems if multiple mechanisms are used!\n"); + p = locate_symbol(dl, "krb5_gss_release_oid", ""); + if (p == NULL || p == (void *) -1) { + fprintf(stderr, "ERROR: Unable to locate function " + "gss_internal_release_oid or " + "gss_release_oid in krb5 mechanism library\n"); + return NULL; + } + } + heimdal_krb5_initialized = 1; + return (&heimdal_krb5_mechanism); +} +#endif diff -puN /dev/null support/gssapi/g_oid_ops.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_oid_ops.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,121 @@ +/* + * lib/gssapi/mechglue/g_oid_ops.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs + */ + +#include +#include "mglueP.h" +/* should include to get protos #include "../generic/gssapiP_generic.h" */ + +extern gss_mechanism *__gss_mechs_array; + +OM_uint32 KRB5_CALLCONV +gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + int i; + OM_uint32 major_status; + + /* first call the gss_internal_release_oid for each mechanism + * until one returns success. gss_internal_release_oid will only return + * success when the OID was recognized as an internal mechanism OID. + * if no mechanisms recognize the OID, then call the generic version. + */ + + for(i=0; __gss_mechs_array[i]->mech_type.length !=0; i++) { + if (__gss_mechs_array[i]->gss_internal_release_oid) { + major_status = __gss_mechs_array[i]->gss_internal_release_oid( +#ifdef USE_MECH_CONTEXT + __gss_mechs_array[i]->context, +#endif + minor_status, + oid); +#ifdef DEBUG + fprintf(stderr, "gss_release_oid (glue): mech returned 0x%08x\n", + major_status); +#endif + if (major_status == GSS_S_COMPLETE) { + return (GSS_S_COMPLETE); + } + } + } + +#ifdef DEBUG + fprintf(stderr, "gss_release_oid (glue): calling " + "generic_gss_release_oid with oid %p (*oid %p)\n", oid, *oid); +#endif + return generic_gss_release_oid(minor_status, oid); +} + +OM_uint32 KRB5_CALLCONV +gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + return generic_gss_create_empty_oid_set(minor_status, oid_set); +} + +OM_uint32 KRB5_CALLCONV +gss_add_oid_set_member(minor_status, member_oid, oid_set) + OM_uint32 *minor_status; + gss_OID member_oid; + gss_OID_set *oid_set; +{ + return generic_gss_add_oid_set_member(minor_status, member_oid, oid_set); +} + +OM_uint32 KRB5_CALLCONV +gss_test_oid_set_member(minor_status, member, set, present) + OM_uint32 *minor_status; + gss_OID member; + gss_OID_set set; + int *present; +{ + return generic_gss_test_oid_set_member(minor_status, member, set, present); +} + +OM_uint32 KRB5_CALLCONV +gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + return generic_gss_oid_to_str(minor_status, oid, oid_str); +} + +OM_uint32 KRB5_CALLCONV +gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + return generic_gss_str_to_oid(minor_status, oid_str, oid); +} + diff -puN /dev/null support/gssapi/g_process_context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_process_context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,75 @@ +/* #ident "@(#)gss_process_context.c 1.9 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_process_context + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_process_context_token (minor_status, + context_handle, + token_buffer) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t token_buffer; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_process_context_token) + status = mech->gss_process_context_token( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + token_buffer); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff -puN /dev/null support/gssapi/g_rel_buffer.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_rel_buffer.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,58 @@ +/* #ident "@(#)g_rel_buffer.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_buffer + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +OM_uint32 KRB5_CALLCONV +gss_release_buffer (minor_status, + buffer) + +OM_uint32 * minor_status; +gss_buffer_t buffer; +{ + if (minor_status) + *minor_status = 0; + + /* if buffer is NULL, return */ + + if(buffer == GSS_C_NO_BUFFER) + return(GSS_S_COMPLETE); + + if ((buffer->length) && + (buffer->value)) { + free(buffer->value); + buffer->length = 0; + buffer->value = NULL; + } + + return (GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_rel_cred.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_rel_cred.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,104 @@ +/* #ident "@(#)gss_release_cred.c 1.15 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_cred + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +OM_uint32 KRB5_CALLCONV +gss_release_cred(minor_status, + cred_handle) + +OM_uint32 * minor_status; +gss_cred_id_t * cred_handle; + +{ + OM_uint32 status, temp_status; + int j; + gss_union_cred_t union_cred; + gss_mechanism mech; + + gss_initialize(); + + if (minor_status) + *minor_status = 0; + + /* if the cred_handle is null, return a NO_CRED error */ + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return(GSS_S_NO_CRED); + + /* + * Loop through the union_cred struct, selecting the approprate + * underlying mechanism routine and calling it. At the end, + * release all of the storage taken by the union_cred struct. + */ + + union_cred = (gss_union_cred_t) *cred_handle; + *cred_handle = NULL; + + if (union_cred == NULL) + return GSS_S_NO_CRED; + + status = GSS_S_COMPLETE; + + for(j=0; j < union_cred->count; j++) { + + mech = __gss_get_mechanism (&union_cred->mechs_array[j]); + + if (union_cred->mechs_array[j].elements) + free(union_cred->mechs_array[j].elements); + if (mech) { + if (mech->gss_release_cred) { + temp_status = mech->gss_release_cred +#ifdef USE_MECH_CONTEXT + (mech->context, +#else + ( +#endif + minor_status, + &union_cred->cred_array[j]); + + if (temp_status != GSS_S_COMPLETE) + status = GSS_S_NO_CRED; + + } else + status = GSS_S_NO_CRED; + } else + status = GSS_S_NO_CRED; + } + + gss_release_buffer(minor_status, &union_cred->auxinfo.name); + free(union_cred->cred_array); + free(union_cred->mechs_array); + free(union_cred); + + return(status); +} diff -puN /dev/null support/gssapi/g_rel_name.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_rel_name.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,92 @@ +/* #ident "@(#)gss_release_name.c 1.2 95/05/09 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_name + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +OM_uint32 KRB5_CALLCONV +gss_release_name (minor_status, + input_name) + +OM_uint32 * minor_status; +gss_name_t * input_name; + +{ + gss_union_name_t union_name; + + /* if input_name is NULL, return error */ + +#ifdef DEBUG + fprintf(stderr, "gss_release_name: input_name %p *input_name %p\n", + input_name, *input_name); +#endif + if (input_name == 0) + return(GSS_S_BAD_NAME); + + /* + * free up the space for the external_name and then + * free the union_name descriptor + */ + + union_name = (gss_union_name_t) *input_name; + *input_name = 0; + *minor_status = 0; + + if (union_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + if (union_name->name_type != GSS_C_NO_OID) + mech_gss_release_oid(minor_status, &union_name->name_type, + union_name->gss_mech); + + free(union_name->external_name->value); + free(union_name->external_name); + + if (union_name->mech_type) { +#ifdef DEBUG + fprintf(stderr, + "gss_release_name: releasing internal name %p and oid %p\n", + union_name->mech_name, union_name->mech_type); +#endif + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + mech_gss_release_oid(minor_status, &union_name->mech_type, + union_name->gss_mech); + } + +#ifdef DEBUG + fprintf(stderr, "gss_release_name: freeing union_name %p\n", union_name); +#endif + free(union_name); + + return(GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_rel_oid_set.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_rel_oid_set.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,63 @@ +/* #ident "@(#)gss_release_oid_set.c 1.12 95/08/23 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_oid_set + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +OM_uint32 KRB5_CALLCONV +gss_release_oid_set (minor_status, + set) + +OM_uint32 * minor_status; +gss_OID_set * set; +{ + size_t index; + gss_OID oid; + if (minor_status) + *minor_status = 0; + + if (set ==NULL) + return GSS_S_COMPLETE; + + if (*set == GSS_C_NULL_OID_SET) + return(GSS_S_COMPLETE); + + for (index=0; index<(*set)->count; index++) { + oid = &(*set)->elements[index]; + free(oid->elements); + } + free((*set)->elements); + free(*set); + + *set = GSS_C_NULL_OID_SET; + + return(GSS_S_COMPLETE); +} diff -puN /dev/null support/gssapi/g_seal.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_seal.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,155 @@ +/* #ident "@(#)gss_seal.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_seal + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_seal (minor_status, + context_handle, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +int conf_req_flag; +int qop_req; +gss_buffer_t input_message_buffer; +int * conf_state; +gss_buffer_t output_message_buffer; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_seal) + status = mech->gss_seal( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_wrap (minor_status, + context_handle, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +int conf_req_flag; +gss_qop_t qop_req; +gss_buffer_t input_message_buffer; +int * conf_state; +gss_buffer_t output_message_buffer; + +{ + return gss_seal(minor_status, context_handle, conf_req_flag, + (int) qop_req, input_message_buffer, conf_state, + output_message_buffer); +} + +/* + * New for V2 + */ +OM_uint32 KRB5_CALLCONV +gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, + qop_req, req_output_size, max_input_size) + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + gss_qop_t qop_req; + OM_uint32 req_output_size; + OM_uint32 *max_input_size; +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (!mech) + return (GSS_S_NO_CONTEXT); + + if (!mech->gss_wrap_size_limit) + return (GSS_S_BAD_BINDINGS); + +#ifdef USE_MECH_CONTEXT + status = mech->gss_wrap_size_limit(mech->context, minor_status, +#else + status = mech->gss_wrap_size_limit(minor_status, +#endif + context_handle, conf_req_flag, qop_req, + req_output_size, max_input_size); + return(status); +} diff -puN /dev/null support/gssapi/g_set_allowable_enctypes.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_set_allowable_enctypes.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,81 @@ +/* #ident "@(#)gss_set_allowable_enctype.c 1.9 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_set_allowable_enctypes + */ + +#include "mglueP.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#include + +OM_uint32 KRB5_CALLCONV +gss_set_allowable_enctypes(minor_status, + cred_handle, + mech_type, + num_ktypes, + ktypes) + +OM_uint32 * minor_status; +gss_cred_id_t cred_handle; +gss_OID mech_type; +OM_uint32 num_ktypes; +void * ktypes; + +{ + gss_union_cred_t union_cred; + gss_mechanism mech; + gss_cred_id_t mech_cred; + + gss_initialize(); + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return (GSS_S_NO_CRED); + + if ((mech = __gss_get_mechanism(mech_type)) == NULL) + return (GSS_S_BAD_MECH); + + if (!mech->gss_set_allowable_enctypes) + return (GSS_S_FAILURE); + + /* get the mechanism-specific cred handle */ + + union_cred = (gss_union_cred_t) cred_handle; + mech_cred = __gss_get_mechanism_cred(union_cred, mech_type); + + if (mech_cred == GSS_C_NO_CREDENTIAL) + return (GSS_S_NO_CRED); + + /* Call the mechanism-specific routine */ +#ifdef USE_MECH_CONTEXT + return (mech->gss_set_allowable_enctypes(mech->context, minor_status, +#else + return (mech->gss_set_allowable_enctypes(minor_status, +#endif + mech_cred, num_ktypes, ktypes)); +} + diff -puN /dev/null support/gssapi/g_sign.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_sign.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,99 @@ +/* #ident "@(#)gss_sign.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_sign + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_sign (minor_status, + context_handle, + qop_req, + message_buffer, + msg_token) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +int qop_req; +gss_buffer_t message_buffer; +gss_buffer_t msg_token; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_sign) + status = mech->gss_sign( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + qop_req, + message_buffer, + msg_token); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_get_mic (minor_status, + context_handle, + qop_req, + message_buffer, + msg_token) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_qop_t qop_req; +gss_buffer_t message_buffer; +gss_buffer_t msg_token; + +{ + return (gss_sign(minor_status, context_handle, (int) qop_req, + message_buffer, msg_token)); +} + diff -puN /dev/null support/gssapi/gssd_pname_to_uid.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/gssd_pname_to_uid.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,71 @@ +/* #ident "@(#)gssd_pname_to_uid.c 1.5 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routines that test the mech id either passed in to + * gss_init_sec_contex() or gss_accept_sec_context() or within the glue + * routine supported version of the security context and then call + * the appropriate underlying mechanism library procedure. + * + */ + +#include "mglueP.h" + +int gssd_pname_to_uid(pname, name_type, mech_type, uid) + +char * pname; +gss_OID name_type; +gss_OID mech_type; +uid_t * uid; +{ + int status; + gss_mechanism mech; + + gss_initialize(); + + /* + * find the appropriate mechanism specific pname_to_uid procedure and + * call it. + */ + + mech = __gss_get_mechanism (mech_type); + + if (mech) { + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + if (mech->pname_to_uid) +#ifdef USE_MECH_CONTEXT + status = mech->pname_to_uid(mech->context, +#else + status = mech->pname_to_uid( +#endif + pname, name_type, mech_type, uid); + else + status = GSS_S_BAD_MECH; + } else + status = GSS_S_BAD_MECH; + + return(status); +} diff -puN /dev/null support/gssapi/g_unseal.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_unseal.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,105 @@ +/* #ident "@(#)gss_unseal.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_unseal + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_unseal (minor_status, + context_handle, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t input_message_buffer; +gss_buffer_t output_message_buffer; +int * conf_state; +int * qop_state; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_unseal) + status = mech->gss_unseal( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_unwrap (minor_status, + context_handle, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t input_message_buffer; +gss_buffer_t output_message_buffer; +int * conf_state; +gss_qop_t * qop_state; + +{ + return (gss_unseal(minor_status, context_handle, + input_message_buffer, + output_message_buffer, + conf_state, (int *) qop_state)); +} diff -puN /dev/null support/gssapi/g_verify.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/g_verify.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,137 @@ +/* #ident "@(#)gss_verify.c 1.9 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_verify + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_verify (minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t message_buffer; +gss_buffer_t token_buffer; +int * qop_state; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_verify) + status = mech->gss_verify( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + message_buffer, + token_buffer, + qop_state); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_verify_mic (minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t message_buffer; +gss_buffer_t token_buffer; +gss_qop_t * qop_state; + +{ +/* + return (gss_verify(minor_status, context_handle, + message_buffer, token_buffer, (int *) qop_state)); + */ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_verify_mic) { + status = mech->gss_verify_mic( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + message_buffer, + token_buffer, + qop_state); + return (status); + } + else + return (gss_verify(minor_status, context_handle, + message_buffer, token_buffer, + (int *) qop_state)); + } + + return(GSS_S_NO_CONTEXT); +} diff -puN /dev/null support/gssapi/Makefile --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/Makefile 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,24 @@ +# +# libgssapi.a +# gssapi mechanism-switching layer +# + +LIBNAME = libgssapi.a +SRCS = g_accept_sec_context.c g_acquire_cred.c g_compare_name.c \ + g_context_time.c g_delete_sec_context.c g_dsp_name.c g_dsp_status.c \ + g_dup_name.c gen_oids.c g_exp_sec_context.c g_glue.c g_imp_name.c \ + g_imp_sec_context.c g_indicate_mechs.c g_initialize.c \ + g_init_sec_context.c g_inq_context.c g_inq_cred.c g_inq_names.c \ + g_mechname.c g_mit_krb5_mech.c g_oid_ops.c g_process_context.c \ + g_rel_buffer.c g_rel_cred.c g_rel_name.c g_rel_oid_set.c g_seal.c \ + g_sign.c gssd_pname_to_uid.c g_unseal.c g_verify.c oid_ops.c \ + g_set_allowable_enctypes.c + +OBJS = $(SRCS:.c=.o) + +include $(TOP)rules.mk + +CFLAGS += -DKRB5_VERSION=$(KRB5_VERSION) -I$(TOP)/support/include + +install:: + @: diff -puN /dev/null support/gssapi/mechglue.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/mechglue.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,46 @@ +/* #ident "@(#)mechglue.h 1.13 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This header contains the mechglue definitions. + */ + +#ifndef _GSS_MECHGLUE_H +#define _GSS_MECHGLUE_H + +#include + +/********************************************************/ +/* GSSAPI Extension functions -- these functions aren't */ +/* in the GSSAPI, but they are provided in this library */ + +int gssd_pname_to_uid (char *, gss_OID, gss_OID, uid_t *); +void gss_initialize (void); +OM_uint32 gss_set_allowable_enctypes( OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_OID, /* mech type */ + OM_uint32, /* num_ktypes */ + void * /* ktypes */); + +#endif /* _GSS_MECHGLUE_H */ diff -puN /dev/null support/gssapi/mglueP.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/mglueP.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,503 @@ +/* #ident "@(#)mglueP.h 1.2 96/01/18 SMI" */ + +/* + * This header contains the private mechglue definitions. + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ifndef _GSS_MECHGLUEP_H +#define _GSS_MECHGLUEP_H + +#include "mechglue.h" + +/* + * Array of context IDs typed by mechanism OID + */ +typedef struct gss_union_ctx_id_t { + gss_OID mech_type; + gss_ctx_id_t internal_ctx_id; +} gss_union_ctx_id_desc, *gss_union_ctx_id_t; + +/* + * Structure for holding list of mechanism-specific name types + */ +typedef struct gss_mech_spec_name_t { + gss_OID name_type; + gss_OID mech; + struct gss_mech_spec_name_t *next, *prev; +} gss_mech_spec_name_desc, *gss_mech_spec_name; + +/* + * Credential auxiliary info, used in the credential structure + */ +typedef struct gss_union_cred_auxinfo { + gss_buffer_desc name; + gss_OID name_type; + time_t creation_time; + OM_uint32 time_rec; + int cred_usage; +} gss_union_cred_auxinfo; + +/* + * Set of Credentials typed on mechanism OID + */ +typedef struct gss_union_cred_t { + int count; + gss_OID mechs_array; + gss_cred_id_t * cred_array; + gss_union_cred_auxinfo auxinfo; +} gss_union_cred_desc, *gss_union_cred_t; + +/********************************************************/ +/* The Mechanism Dispatch Table -- a mechanism needs to */ +/* define one of these and provide a function to return */ +/* it to initialize the GSSAPI library */ + +/* + * This is the definition of the mechs_array struct, which is used to + * define the mechs array table. This table is used to indirectly + * access mechanism specific versions of the gssapi routines through + * the routines in the glue module (gssd_mech_glue.c) + * + * This contants all of the functions defined in gssapi.h except for + * gss_release_buffer() and gss_release_oid_set(), which I am + * assuming, for now, to be equal across mechanisms. + */ + +typedef struct gss_config { + gss_OID_desc mech_type; + void * context; + OM_uint32 (*gss_acquire_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + gss_OID_set, /* desired_mechs */ + int, /* cred_usage */ + gss_cred_id_t*, /* output_cred_handle */ + gss_OID_set*, /* actual_mechs */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_release_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_cred_id_t* /* cred_handle */ + ); + OM_uint32 (*gss_init_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t*, /* context_handle */ + gss_name_t, /* target_name */ + gss_OID, /* mech_type */ + OM_uint32, /* req_flags */ + OM_uint32, /* time_req */ + gss_channel_bindings_t, /* input_chan_bindings */ + gss_buffer_t, /* input_token */ + gss_OID*, /* actual_mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32*, /* ret_flags */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_accept_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_cred_id_t, /* verifier_cred_handle */ + gss_buffer_t, /* input_token_buffer */ + gss_channel_bindings_t, /* input_chan_bindings */ + gss_name_t*, /* src_name */ + gss_OID*, /* mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32*, /* ret_flags */ + OM_uint32*, /* time_rec */ + gss_cred_id_t* /* delegated_cred_handle */ + ); + OM_uint32 (*gss_process_context_token) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + ); + OM_uint32 (*gss_delete_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t /* output_token */ + ); + OM_uint32 (*gss_context_time) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_sign) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + OM_uint32 (*gss_verify) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + OM_uint32 (*gss_seal) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int*, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + OM_uint32 (*gss_unseal) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int*, /* conf_state */ + int* /* qop_state */ + ); + OM_uint32 (*gss_display_status) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + gss_OID, /* mech_type */ + OM_uint32*, /* message_context */ + gss_buffer_t /* status_string */ + ); + OM_uint32 (*gss_indicate_mechs) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_OID_set* /* mech_set */ + ); + OM_uint32 (*gss_compare_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int* /* name_equal */ + ); + OM_uint32 (*gss_display_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID* /* output_name_type */ + ); + OM_uint32 (*gss_import_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + gss_OID, /* input_name_type */ + gss_name_t* /* output_name */ + ); + OM_uint32 (*gss_release_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t* /* input_name */ + ); + OM_uint32 (*gss_inquire_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + int *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + OM_uint32 (*gss_add_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* input_cred_handle */ + gss_name_t, /* desired_name */ + gss_OID, /* desired_mech */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 *, /* initiator_time_rec */ + OM_uint32 * /* acceptor_time_rec */ + ); + OM_uint32 (*gss_export_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* interprocess_token */ + ); + OM_uint32 (*gss_import_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t * /* context_handle */ + ); + OM_uint32 (*gss_inquire_cred_by_mech) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_OID, /* mech_type */ + gss_name_t *, /* name */ + OM_uint32 *, /* initiator_lifetime */ + OM_uint32 *, /* acceptor_lifetime */ + gss_cred_usage_t * /* cred_usage */ + ); + OM_uint32 (*gss_inquire_names_for_mech) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_OID, /* mechanism */ + gss_OID_set * /* name_types */ + ); + OM_uint32 (*gss_inquire_context) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_name_t *, /* src_name */ + gss_name_t *, /* targ_name */ + OM_uint32 *, /* lifetime_rec */ + gss_OID *, /* mech_type */ + OM_uint32 *, /* ctx_flags */ + int *, /* locally_initiated */ + int * /* open */ + ); + OM_uint32 (*gss_internal_release_oid) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_OID * /* OID */ + ); + OM_uint32 (*gss_wrap_size_limit) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + OM_uint32, /* req_output_size */ + OM_uint32 * /* max_input_size */ + ); + OM_uint32 (*pname_to_uid) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + char *, /* pname */ + gss_OID, /* name type */ + gss_OID, /* mech type */ + uid_t * /* uid */ + ); + OM_uint32 (*gss_duplicate_name) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_name_t * /* dest_name */ + ); + OM_uint32 (*gss_set_allowable_enctypes) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + OM_uint32, /* num_ktypes */ + void * /* ktypes */ + ); + OM_uint32 (*gss_verify_mic) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + +} *gss_mechanism; + +/* + * Generic GSSAPI names. A name can either be a generic name, or a + * mechanism specific name.... + */ +typedef struct gss_union_name_t { + gss_mechanism gss_mech; + gss_OID name_type; + gss_buffer_t external_name; + /* + * These last two fields are only filled in for mechanism + * names. + */ + gss_OID mech_type; + gss_name_t mech_name; +} gss_union_name_desc, *gss_union_name_t; + +/********************************************************/ +/* Internal mechglue routines */ + +gss_mechanism __gss_get_mechanism (gss_OID); +OM_uint32 __gss_get_mech_type (gss_OID, gss_buffer_t); +OM_uint32 __gss_import_internal_name (OM_uint32 *, gss_OID, gss_union_name_t, + gss_name_t *); +OM_uint32 __gss_display_internal_name (OM_uint32 *, gss_OID, gss_name_t, + gss_buffer_t, gss_OID *); +OM_uint32 __gss_release_internal_name (OM_uint32 *, gss_OID, gss_name_t *); + +OM_uint32 __gss_convert_name_to_union_name + (OM_uint32 *, /* minor_status */ + gss_mechanism, /* mech */ + gss_name_t, /* internal_name */ + gss_name_t * /* external_name */ + ); +gss_cred_id_t __gss_get_mechanism_cred + (gss_union_cred_t, /* union_cred */ + gss_OID /* mech_type */ + ); + +OM_uint32 generic_gss_release_oid + (OM_uint32 *, /* minor_status */ + gss_OID * /* oid */ + ); + +OM_uint32 mech_gss_release_oid + (OM_uint32 *, /* minor_status */ + gss_OID *, /* oid */ + gss_mechanism /* gss_mech */ + ); + +OM_uint32 generic_gss_copy_oid + (OM_uint32 *, /* minor_status */ + gss_OID, /* oid */ + gss_OID * /* new_oid */ + ); + +OM_uint32 generic_gss_create_empty_oid_set + (OM_uint32 *, /* minor_status */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_add_oid_set_member + (OM_uint32 *, /* minor_status */ + gss_OID, /* member_oid */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_test_oid_set_member + (OM_uint32 *, /* minor_status */ + gss_OID, /* member */ + gss_OID_set, /* set */ + int * /* present */ + ); + +OM_uint32 generic_gss_oid_to_str + (OM_uint32 *, /* minor_status */ + gss_OID, /* oid */ + gss_buffer_t /* oid_str */ + ); + +OM_uint32 generic_gss_str_to_oid + (OM_uint32 *, /* minor_status */ + gss_buffer_t, /* oid_str */ + gss_OID * /* oid */ + ); + + +gss_OID gss_find_mechanism_from_name_type (gss_OID); /* name_type */ + +OM_uint32 gss_add_mech_name_type + (OM_uint32 *, /* minor_status */ + gss_OID, /* name_type */ + gss_OID /* mech */ + ); + +#endif /* _GSS_MECHGLUEP_H */ diff -puN /dev/null support/gssapi/oid_ops.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/oid_ops.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,449 @@ +/* + * lib/gssapi/generic/oid_ops.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs + */ + +#include "mglueP.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include + +OM_uint32 +generic_gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + *minor_status = 0; +#ifdef DEBUG + static int printed = 0; + + if (!printed++) + fprintf(stderr, "gss_generic_release_oid (glue):\n" + " GSS_C_NT_USER_NAME %p\n" + " GSS_C_NT_MACHINE_UID_NAME %p\n" + " GSS_C_NT_STRING_UID_NAME %p\n" + " GSS_C_NT_HOSTBASED_SERVICE %p\n" + " GSS_C_NT_ANONYMOUS %p\n" + " GSS_C_NT_EXPORT_NAME %p\n", + GSS_C_NT_USER_NAME, GSS_C_NT_MACHINE_UID_NAME, + GSS_C_NT_STRING_UID_NAME, GSS_C_NT_HOSTBASED_SERVICE, + GSS_C_NT_ANONYMOUS, GSS_C_NT_EXPORT_NAME); +#endif + + if (*oid == GSS_C_NO_OID) + return(GSS_S_COMPLETE); + + /* + * The V2 API says the following! + * + * gss_release_oid[()] will recognize any of the GSSAPI's own OID values, + * and will silently ignore attempts to free these OIDs; for other OIDs + * it will call the C free() routine for both the OID data and the + * descriptor. This allows applications to freely mix their own heap- + * allocated OID values with OIDs returned by GSS-API. + */ + if ((*oid != GSS_C_NT_USER_NAME) && + (*oid != GSS_C_NT_MACHINE_UID_NAME) && + (*oid != GSS_C_NT_STRING_UID_NAME) && + (*oid != GSS_C_NT_HOSTBASED_SERVICE) && + (*oid != GSS_C_NT_ANONYMOUS) && + (*oid != GSS_C_NT_EXPORT_NAME)) { +#ifdef DEBUG + fprintf(stderr, "generic_gss_release_oid (glue): freeing *oid at %p\n", + *oid); +#endif + free((*oid)->elements); + free(*oid); + } + *oid = GSS_C_NO_OID; + return(GSS_S_COMPLETE); +} + +OM_uint32 +mech_gss_release_oid(minor_status, oid, gss_mech) + OM_uint32 *minor_status; + gss_OID *oid; + gss_mechanism gss_mech; +{ + *minor_status = 0; + +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: *oid %p, gss_mech %p\n", + *oid, gss_mech); +#endif + if (*oid == GSS_C_NO_OID) + return (GSS_S_COMPLETE); + + if (gss_mech == NULL) { +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: no gss_mech!\n"); +#endif + return (generic_gss_release_oid(minor_status, oid)); + } + + if (!gss_mech->gss_internal_release_oid) { +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: mechanism has " + "no gss_internal_release_oid function! using " + "generic_gss_release_oid\n"); +#endif + return (generic_gss_release_oid(minor_status, oid)); + } + +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: calling mechanism's " + "gss_internal_release_oid\n"); +#endif + return (gss_mech->gss_internal_release_oid(minor_status, oid)); +} + +OM_uint32 +generic_gss_copy_oid(minor_status, oid, new_oid) + OM_uint32 *minor_status; + gss_OID oid, *new_oid; +{ + gss_OID p; + + if (oid == GSS_C_NO_OID) { + *new_oid = GSS_C_NO_OID; + return (GSS_S_COMPLETE); + } + + p = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!p) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + p->length = oid->length; + p->elements = malloc(p->length); + if (!p->elements) { + free(p); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(p->elements, oid->elements, p->length); + *new_oid = p; + return (GSS_S_COMPLETE); +} + + +OM_uint32 +generic_gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + if ((*oid_set = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)))) { + memset(*oid_set, 0, sizeof(gss_OID_set_desc)); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } +} + +OM_uint32 +generic_gss_add_oid_set_member(minor_status, member_oid, oid_set) + OM_uint32 *minor_status; + gss_OID member_oid; + gss_OID_set *oid_set; +{ + gss_OID elist; + gss_OID lastel; + + elist = (*oid_set)->elements; + /* Get an enlarged copy of the array */ + if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * + sizeof(gss_OID_desc)))) { + /* Copy in the old junk */ + if (elist) + memcpy((*oid_set)->elements, + elist, + ((*oid_set)->count * sizeof(gss_OID_desc))); + + /* Duplicate the input element */ + lastel = &(*oid_set)->elements[(*oid_set)->count]; + if ((lastel->elements = + (void *) malloc((size_t) member_oid->length))) { + /* Success - copy elements */ + memcpy(lastel->elements, member_oid->elements, + (size_t) member_oid->length); + /* Set length */ + lastel->length = member_oid->length; + + /* Update count */ + (*oid_set)->count++; + if (elist) + free(elist); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else + free((*oid_set)->elements); + } + /* Failure - restore old contents of list */ + (*oid_set)->elements = elist; + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_test_oid_set_member(minor_status, member, set, present) + OM_uint32 *minor_status; + gss_OID member; + gss_OID_set set; + int *present; +{ + size_t i; + int result; + + result = 0; + for (i=0; icount; i++) { + if ((set->elements[i].length == member->length) && + !memcmp(set->elements[i].elements, + member->elements, + (size_t) member->length)) { + result = 1; + break; + } + } + *present = result; + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +/* + * OID<->string routines. These are uuuuugly. + */ +OM_uint32 +generic_gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + char numstr[128]; + unsigned long number; + int numshift; + size_t string_length; + size_t i; + unsigned char *cp; + char *bp; + + /* Decoded according to krb5/gssapi_krb5.c */ + + /* First determine the size of the string */ + string_length = 0; + number = 0; + numshift = 0; + cp = (unsigned char *) oid->elements; + number = (unsigned long) cp[0]; + sprintf(numstr, "%ld ", number/40); + string_length += strlen(numstr); + sprintf(numstr, "%ld ", number%40); + string_length += strlen(numstr); + for (i=1; ilength; i++) { + if ( (size_t) (numshift+7) < (sizeof(unsigned long)*8)) { + number = (number << 7) | (cp[i] & 0x7f); + numshift += 7; + } + else { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + if ((cp[i] & 0x80) == 0) { + sprintf(numstr, "%ld ", number); + string_length += strlen(numstr); + number = 0; + numshift = 0; + } + } + /* + * If we get here, we've calculated the length of "n n n ... n ". Add 4 + * here for "{ " and "}\0". + */ + string_length += 4; + if ((bp = (char *) malloc(string_length))) { + strcpy(bp, "{ "); + number = (unsigned long) cp[0]; + sprintf(numstr, "%ld ", number/40); + strcat(bp, numstr); + sprintf(numstr, "%ld ", number%40); + strcat(bp, numstr); + number = 0; + cp = (unsigned char *) oid->elements; + for (i=1; ilength; i++) { + number = (number << 7) | (cp[i] & 0x7f); + if ((cp[i] & 0x80) == 0) { + sprintf(numstr, "%ld ", number); + strcat(bp, numstr); + number = 0; + } + } + strcat(bp, "}"); + oid_str->length = strlen(bp)+1; + oid_str->value = (void *) bp; + *minor_status = 0; + return(GSS_S_COMPLETE); + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + char *cp, *bp, *startp; + int brace; + long numbuf; + long onumbuf; + OM_uint32 nbytes; + int index; + unsigned char *op; + + brace = 0; + bp = (char *) oid_str->value; + cp = bp; + /* Skip over leading space */ + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (*bp == '{') { + brace = 1; + bp++; + } + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + startp = bp; + nbytes = 0; + + /* + * The first two numbers are chewed up by the first octet. + */ + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + nbytes++; + while (isdigit(*bp)) { + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + } + if (brace && (*bp != '}')) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + + /* + * Phew! We've come this far, so the syntax is good. + */ + if ((*oid = (gss_OID) malloc(sizeof(gss_OID_desc)))) { + if (((*oid)->elements = (void *) malloc((size_t) nbytes))) { + (*oid)->length = nbytes; + op = (unsigned char *) (*oid)->elements; + bp = startp; + sscanf(bp, "%ld", &numbuf); + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + onumbuf = 40*numbuf; + sscanf(bp, "%ld", &numbuf); + onumbuf += numbuf; + *op = (unsigned char) onumbuf; + op++; + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + while (isdigit(*bp)) { + sscanf(bp, "%ld", &numbuf); + nbytes = 0; + /* Have to fill in the bytes msb-first */ + onumbuf = numbuf; + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + numbuf = onumbuf; + op += nbytes; + index = -1; + while (numbuf) { + op[index] = (unsigned char) numbuf & 0x7f; + if (index != -1) + op[index] |= 0x80; + index--; + numbuf >>= 7; + } + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + } + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else { + free(*oid); + *oid = GSS_C_NO_OID; + } + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + diff -puN /dev/null support/gssapi/SAMPLE_gssapi_mech.conf --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/gssapi/SAMPLE_gssapi_mech.conf 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,19 @@ +# GSSAPI Mechanism Definitions +# +# This configuration file determines which GSS-API mechanisms +# the gssd code should use +# +# NOTE: +# The initiaiization function "mechglue_internal_krb5_init" +# is used for the MIT krb5 gssapi mechanism. This special +# function name indicates that an internal function should +# be used to determine the entry points for the MIT gssapi +# mechanism funtions. +# +# library initialization function +# ================================ ========================== +# The MIT K5 gssapi library, use special function for initialization. +/usr/lib/libgssapi_krb5.so mechglue_internal_krb5_init +# +# The SPKM3 gssapi library function. Use the function spkm3_gss_initialize. +# /usr/local/gss_mechs/spkm/spkm3/libgssapi_spkm3.so spkm3_gss_initialize diff -puN support/include/config.h.in~CITI_NFS4_ALL support/include/config.h.in --- nfs-utils-1.0.6/support/include/config.h.in~CITI_NFS4_ALL 2004-10-27 18:02:45.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/include/config.h.in 2004-10-27 18:02:49.000000000 -0400 @@ -23,3 +23,23 @@ * but lockd from using this service. */ #undef RESTRICTED_STATD + +/* Define this if you want support for rpcsec_gss with + * the MIT krb5 mechanism compiled in */ +#undef HAVE_KRB5 + +/* Define this if you want support for rpcsec_gss with + * the Heimdal krb5 mechanism compiled in */ +#undef HAVE_HEIMDAL + +/* Define this if the Kerberos gssapi library has function + * gss_krb5_export_lucid_sec_context */ +#undef HAVE_LUCID_CONTEXT_SUPPORT + +/* Define this if the Kerberos gssapi library has function + * gss_krb5_set_allowable_enctypes */ +#undef HAVE_SET_ALLOWABLE_ENCTYPES + +/* Define this if the Kerberos gssapi library has function + * gss_krb5_cache_name */ +#undef HAVE_GSS_KRB5_CCACHE_NAME diff -puN support/include/exportfs.h~CITI_NFS4_ALL support/include/exportfs.h --- nfs-utils-1.0.6/support/include/exportfs.h~CITI_NFS4_ALL 2004-10-27 18:02:45.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/include/exportfs.h 2004-10-27 18:02:49.000000000 -0400 @@ -19,6 +19,7 @@ enum { MCL_WILDCARD, MCL_NETGROUP, MCL_ANONYMOUS, + MCL_GSS, MCL_MAXTYPES }; diff -puN /dev/null support/include/gssapi/gssapi.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/include/gssapi/gssapi.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,846 @@ +/* This is the gssapi.h prologue. */ +/* It contains some choice pieces of autoconf.h */ +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define SIZEOF_SHORT 2 +#define HAVE_STDARG_H 1 +/* #undef HAVE_VARARGS_H */ +/* #undef HAVE_MACSOCK_H */ +#define HAVE_NETINET_IN_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_FILE_H 1 +#define HAVE_SYS_PARAM_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_UNISTD_H 1 +/* #undef HAVE_XOM_H */ +#define USE_DIRENT_H 1 +/* End of gssapi.h prologue. */ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GSSAPI_H_ +#define _GSSAPI_H_ + +/* + * Determine platform-dependent configuration. + */ + +#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__)) + #include + #if TARGET_RT_MAC_CFM + #error "Use KfM 4.0 SDK headers for CFM compilation." + #endif + + /* This is an API divergence in 1.2.3. This will be reconciled in 1.3, when + all platforms will have RFC-compliant OID declarations. */ + #define GSS_RFC_COMPLIANT_OIDS 1 +#else + #define GSS_RFC_COMPLIANT_OIDS 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if TARGET_OS_MAC + #if defined(__MWERKS__) + #pragma import on + #pragma enumsalwaysint on + #endif + #pragma options align=mac68k +#endif + +#if defined(_MSDOS) || defined(_WIN32) +#include +#endif + +/* #ifndef KRB5_CALLCONV */ +#define KRB5_CALLCONV +#define KRB5_CALLCONV_C +#define KRB5_DLLIMP +#define GSS_DLLIMP +#define KRB5_EXPORTVAR +/* #endif */ +#ifndef FAR +#define FAR +#define NEAR +#endif + +#define GSS_SIZEOF_INT SIZEOF_INT +#define GSS_SIZEOF_LONG SIZEOF_LONG +#define GSS_SIZEOF_SHORT SIZEOF_SHORT + +/* + * Make sure we have a definition for PROTOTYPE. + */ +#if !defined(PROTOTYPE) +#if defined(__STDC__) || defined(__cplusplus) || defined(_MSDOS) || defined(_WIN32) || defined(__ultrix) +#define PROTOTYPE(x) x +#else +#define PROTOTYPE(x) () +#endif +#endif + +/* + * First, include stddef.h to get size_t defined. + */ +#if HAVE_STDDEF_H +#include +#endif /* HAVE_STDDEF_H */ + +/* + * POSIX says that sys/types.h is where size_t is defined. + */ +#ifndef macintosh +#include +#endif + +/* + * If the platform supports the xom.h header file, it should be included here. + */ +#if HAVE_XOM_H +#include +#endif /* HAVE_XOM_H */ + +/* + * $Id: gssapi.h,v 1.1 2004/10/19 00:22:57 neilbrown Exp $ + */ + +/* + * First, define the three platform-dependent pointer types. + */ + +typedef void FAR * gss_name_t; +typedef void FAR * gss_cred_id_t; +typedef void FAR * gss_ctx_id_t; + +/* + * The following type must be defined as the smallest natural unsigned integer + * supported by the platform that has at least 32 bits of precision. + */ +#if (GSS_SIZEOF_SHORT == 4) +typedef unsigned short gss_uint32; +typedef short gss_int32; +#elif (GSS_SIZEOF_INT == 4) +typedef unsigned int gss_uint32; +typedef int gss_int32; +#elif (GSS_SIZEOF_LONG == 4) +typedef unsigned long gss_uint32; +typedef long gss_int32; +#endif + +#ifdef OM_STRING +/* + * We have included the xom.h header file. Use the definition for + * OM_object identifier. + */ +typedef OM_object_identifier gss_OID_desc, *gss_OID; +#else /* OM_STRING */ +/* + * We can't use X/Open definitions, so roll our own. + */ +typedef gss_uint32 OM_uint32; + +typedef struct gss_OID_desc_struct { + OM_uint32 length; + void FAR *elements; +} gss_OID_desc, FAR *gss_OID; +#endif /* OM_STRING */ + +typedef struct gss_OID_set_desc_struct { + size_t count; + gss_OID elements; +} gss_OID_set_desc, FAR *gss_OID_set; + +typedef struct gss_buffer_desc_struct { + size_t length; + void FAR *value; +} gss_buffer_desc, FAR *gss_buffer_t; + +typedef struct gss_channel_bindings_struct { + OM_uint32 initiator_addrtype; + gss_buffer_desc initiator_address; + OM_uint32 acceptor_addrtype; + gss_buffer_desc acceptor_address; + gss_buffer_desc application_data; +} FAR *gss_channel_bindings_t; + +/* + * For now, define a QOP-type as an OM_uint32 (pending resolution of ongoing + * discussions). + */ +typedef OM_uint32 gss_qop_t; +typedef int gss_cred_usage_t; + +/* + * Flag bits for context-level services. + */ +#define GSS_C_DELEG_FLAG 1 +#define GSS_C_MUTUAL_FLAG 2 +#define GSS_C_REPLAY_FLAG 4 +#define GSS_C_SEQUENCE_FLAG 8 +#define GSS_C_CONF_FLAG 16 +#define GSS_C_INTEG_FLAG 32 +#define GSS_C_ANON_FLAG 64 +#define GSS_C_PROT_READY_FLAG 128 +#define GSS_C_TRANS_FLAG 256 + +/* + * Credential usage options + */ +#define GSS_C_BOTH 0 +#define GSS_C_INITIATE 1 +#define GSS_C_ACCEPT 2 + +/* + * Status code types for gss_display_status + */ +#define GSS_C_GSS_CODE 1 +#define GSS_C_MECH_CODE 2 + +/* + * The constant definitions for channel-bindings address families + */ +#define GSS_C_AF_UNSPEC 0 +#define GSS_C_AF_LOCAL 1 +#define GSS_C_AF_INET 2 +#define GSS_C_AF_IMPLINK 3 +#define GSS_C_AF_PUP 4 +#define GSS_C_AF_CHAOS 5 +#define GSS_C_AF_NS 6 +#define GSS_C_AF_NBS 7 +#define GSS_C_AF_ECMA 8 +#define GSS_C_AF_DATAKIT 9 +#define GSS_C_AF_CCITT 10 +#define GSS_C_AF_SNA 11 +#define GSS_C_AF_DECnet 12 +#define GSS_C_AF_DLI 13 +#define GSS_C_AF_LAT 14 +#define GSS_C_AF_HYLINK 15 +#define GSS_C_AF_APPLETALK 16 +#define GSS_C_AF_BSC 17 +#define GSS_C_AF_DSS 18 +#define GSS_C_AF_OSI 19 +#define GSS_C_AF_X25 21 + +#define GSS_C_AF_NULLADDR 255 + +/* + * Various Null values. + */ +#define GSS_C_NO_NAME ((gss_name_t) 0) +#define GSS_C_NO_BUFFER ((gss_buffer_t) 0) +#define GSS_C_NO_OID ((gss_OID) 0) +#define GSS_C_NO_OID_SET ((gss_OID_set) 0) +#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0) +#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0) +#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0) +#define GSS_C_EMPTY_BUFFER {0, NULL} + +/* + * Some alternate names for a couple of the above values. These are defined + * for V1 compatibility. + */ +#define GSS_C_NULL_OID GSS_C_NO_OID +#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET + +/* + * Define the default Quality of Protection for per-message services. Note + * that an implementation that offers multiple levels of QOP may either reserve + * a value (for example zero, as assumed here) to mean "default protection", or + * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit + * QOP value. However a value of 0 should always be interpreted by a GSSAPI + * implementation as a request for the default protection level. + */ +#define GSS_C_QOP_DEFAULT 0 + +/* + * Expiration time of 2^32-1 seconds means infinite lifetime for a + * credential or security context + */ +#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful) + + +/* Major status codes */ + +#define GSS_S_COMPLETE 0 + +/* + * Some "helper" definitions to make the status code macros obvious. + */ +#define GSS_C_CALLING_ERROR_OFFSET 24 +#define GSS_C_ROUTINE_ERROR_OFFSET 16 +#define GSS_C_SUPPLEMENTARY_OFFSET 0 +#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul) +#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul) +#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul) + +/* + * The macros that test status codes for error conditions. Note that the + * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now + * evaluates its argument only once. + */ +#define GSS_CALLING_ERROR(x) \ + ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) +#define GSS_ROUTINE_ERROR(x) \ + ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) +#define GSS_SUPPLEMENTARY_INFO(x) \ + ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) +#define GSS_ERROR(x) \ + ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ + (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) + +/* + * Now the actual status code definitions + */ + +/* + * Calling errors: + */ +#define GSS_S_CALL_INACCESSIBLE_READ \ + (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_INACCESSIBLE_WRITE \ + (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_BAD_STRUCTURE \ + (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET) + +/* + * Routine errors: + */ +#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_CREDENTIAL \ + (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CREDENTIALS_EXPIRED \ + (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CONTEXT_EXPIRED \ + (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DUPLICATE_ELEMENT \ + (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NAME_NOT_MN \ + (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET) + +/* + * Supplementary info bits: + */ +#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) +#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) +#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) +#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) +#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) + + +/* + * Finally, function prototypes for the GSSAPI routines. + */ + +/* Reserved static storage for GSS_oids. Comments are quotes from RFC 2744. + * + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant + * GSS_C_NT_USER_NAME should be initialized to point + * to that gss_OID_desc. + */ +extern const gss_OID_desc * const GSS_C_NT_USER_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}. + * The constant GSS_C_NT_MACHINE_UID_NAME should be + * initialized to point to that gss_OID_desc. + */ +extern const gss_OID_desc * const GSS_C_NT_MACHINE_UID_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) string_uid_name(3)}. + * The constant GSS_C_NT_STRING_UID_NAME should be + * initialized to point to that gss_OID_desc. + */ +extern const gss_OID_desc * const GSS_C_NT_STRING_UID_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\x01\x05\x06\x02"}, + * corresponding to an object-identifier value of + * {iso(1) org(3) dod(6) internet(1) security(5) + * nametypes(6) gss-host-based-services(2)). The constant + * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point + * to that gss_OID_desc. This is a deprecated OID value, and + * implementations wishing to support hostbased-service names + * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID, + * defined below, to identify such names; + * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym + * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input + * parameter, but should not be emitted by GSS-API + * implementations +GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; + */ + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x04"}, corresponding to an + * object-identifier value of {iso(1) member-body(2) + * Unites States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4)}. The constant + * GSS_C_NT_HOSTBASED_SERVICE should be initialized + * to point to that gss_OID_desc. + */ +extern const gss_OID_desc * const GSS_C_NT_HOSTBASED_SERVICE; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\01\x05\x06\x03"}, + * corresponding to an object identifier value of + * {1(iso), 3(org), 6(dod), 1(internet), 5(security), + * 6(nametypes), 3(gss-anonymous-name)}. The constant + * and GSS_C_NT_ANONYMOUS should be initialized to point + * to that gss_OID_desc. + */ +extern const gss_OID_desc * const GSS_C_NT_ANONYMOUS; + + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\x01\x05\x06\x04"}, + * corresponding to an object-identifier value of + * {1(iso), 3(org), 6(dod), 1(internet), 5(security), + * 6(nametypes), 4(gss-api-exported-name)}. The constant + * GSS_C_NT_EXPORT_NAME should be initialized to point + * to that gss_OID_desc. + */ +extern const gss_OID_desc * const GSS_C_NT_EXPORT_NAME; + + +/* Function Prototypes */ + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_acquire_cred +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + gss_OID_set, /* desired_mechs */ + gss_cred_usage_t, /* cred_usage */ + gss_cred_id_t FAR *, /* output_cred_handle */ + gss_OID_set FAR *, /* actual_mechs */ + OM_uint32 FAR * /* time_rec */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_cred +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_cred_id_t FAR * /* cred_handle */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_init_sec_context +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t FAR *, /* context_handle */ + gss_name_t, /* target_name */ + gss_OID, /* mech_type (used to be const) */ + OM_uint32, /* req_flags */ + OM_uint32, /* time_req */ + gss_channel_bindings_t, /* input_chan_bindings */ + gss_buffer_t, /* input_token */ + gss_OID FAR *, /* actual_mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32 FAR *, /* ret_flags */ + OM_uint32 FAR * /* time_rec */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_accept_sec_context +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t FAR *, /* context_handle */ + gss_cred_id_t, /* acceptor_cred_handle */ + gss_buffer_t, /* input_token_buffer */ + gss_channel_bindings_t, /* input_chan_bindings */ + gss_name_t FAR *, /* src_name */ + gss_OID FAR *, /* mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32 FAR *, /* ret_flags */ + OM_uint32 FAR *, /* time_rec */ + gss_cred_id_t FAR * /* delegated_cred_handle */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_process_context_token +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_delete_sec_context +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t FAR *, /* context_handle */ + gss_buffer_t /* output_token */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_context_time +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32 FAR * /* time_rec */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_get_mic +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_qop_t, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_verify_mic +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* message_token */ + gss_qop_t * /* qop_state */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_wrap +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int FAR *, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_unwrap +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int FAR *, /* conf_state */ + gss_qop_t FAR * /* qop_state */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_display_status +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + gss_OID, /* mech_type (used to be const) */ + OM_uint32 FAR *, /* message_context */ + gss_buffer_t /* status_string */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_indicate_mechs +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID_set FAR * /* mech_set */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_compare_name +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int FAR * /* name_equal */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_display_name +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID FAR * /* output_name_type */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_import_name +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + gss_OID, /* input_name_type(used to be const) */ + gss_name_t FAR * /* output_name */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_name +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_name_t FAR * /* input_name */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_buffer +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_buffer_t /* buffer */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_oid_set +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID_set FAR * /* set */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_cred +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t FAR *, /* name */ + OM_uint32 FAR *, /* lifetime */ + gss_cred_usage_t FAR *, /* cred_usage */ + gss_OID_set FAR * /* mechanisms */ + )); + +/* Last argument new for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_context +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_name_t FAR *, /* src_name */ + gss_name_t FAR *, /* targ_name */ + OM_uint32 FAR *, /* lifetime_rec */ + gss_OID FAR *, /* mech_type */ + OM_uint32 FAR *, /* ctx_flags */ + int FAR *, /* locally_initiated */ + int FAR * /* open */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_wrap_size_limit +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + OM_uint32, /* req_output_size */ + OM_uint32 * /* max_input_size */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_import_name_object +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + void FAR *, /* input_name */ + gss_OID, /* input_name_type */ + gss_name_t FAR * /* output_name */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_export_name_object +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_name_t, /* input_name */ + gss_OID, /* desired_name_type */ + void FAR * FAR * /* output_name */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_add_cred +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_cred_id_t, /* input_cred_handle */ + gss_name_t, /* desired_name */ + gss_OID, /* desired_mech */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t FAR *, /* output_cred_handle */ + gss_OID_set FAR *, /* actual_mechs */ + OM_uint32 FAR *, /* initiator_time_rec */ + OM_uint32 FAR * /* acceptor_time_rec */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_cred_by_mech +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_OID, /* mech_type */ + gss_name_t FAR *, /* name */ + OM_uint32 FAR *, /* initiator_lifetime */ + OM_uint32 FAR *, /* acceptor_lifetime */ + gss_cred_usage_t FAR * /* cred_usage */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_export_sec_context +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t FAR *, /* context_handle */ + gss_buffer_t /* interprocess_token */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_import_sec_context +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t FAR * /* context_handle */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_oid +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID FAR * /* oid */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_create_empty_oid_set +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID_set FAR * /* oid_set */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_add_oid_set_member +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID, /* member_oid */ + gss_OID_set FAR * /* oid_set */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_test_oid_set_member +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID, /* member */ + gss_OID_set, /* set */ + int FAR * /* present */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_str_to_oid +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_buffer_t, /* oid_str */ + gss_OID FAR * /* oid */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_oid_to_str +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID, /* oid */ + gss_buffer_t /* oid_str */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_names_for_mech +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_OID, /* mechanism */ + gss_OID_set FAR * /* name_types */ + )); + +/* + * The following routines are obsolete variants of gss_get_mic, gss_wrap, + * gss_verify_mic and gss_unwrap. They should be provided by GSSAPI V2 + * implementations for backwards compatibility with V1 applications. Distinct + * entrypoints (as opposed to #defines) should be provided, to allow GSSAPI + * V1 applications to link against GSSAPI V2 implementations. + */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_sign +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_verify +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int FAR * /* qop_state */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_seal +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int FAR *, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + )); + +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_unseal +PROTOTYPE( (OM_uint32 FAR *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int FAR *, /* conf_state */ + int FAR * /* qop_state */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_export_name +PROTOTYPE( (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t /* exported_name */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_duplicate_name +PROTOTYPE( (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_name_t * /* dest_name */ + )); + +/* New for V2 */ +GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_canonicalize_name +PROTOTYPE( (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + const gss_OID, /* mech_type */ + gss_name_t * /* output_name */ + )); + +#if TARGET_OS_MAC + #if defined(__MWERKS__) + #pragma enumsalwaysint reset + #pragma import reset + #endif + #pragma options align=reset +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* XXXX these are not part of the GSSAPI C bindings! (but should be) */ + +#define GSS_CALLING_ERROR_FIELD(x) \ + (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK) +#define GSS_ROUTINE_ERROR_FIELD(x) \ + (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK) +#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \ + (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK) + +/* XXXX This is a necessary evil until the spec is fixed */ +#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE + +#endif /* _GSSAPI_H_ */ diff -puN /dev/null support/include/ha-callout.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/include/ha-callout.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,52 @@ +/* + * support/include/ha-callout.h + * + * High Availability NFS Callout support routines + * + * Copyright (c) 2004, Paul Clements, SteelEye Technology + * + * In order to implement HA NFS, we need several callouts at key + * points in statd and mountd. These callouts all come to ha_callout(), + * which, in turn, calls out to an ha-callout script (not part of nfs-utils; + * defined by -H argument to rpc.statd and rpc.mountd). + */ +#ifndef HA_CALLOUT_H +#define HA_CALLOUT_H + +#include + +extern char *ha_callout_prog; + +static inline void +ha_callout(char *event, char *arg1, char *arg2, int arg3) +{ + char buf[16]; /* should be plenty */ + pid_t pid; + int ret = -1; + + if (!ha_callout_prog) /* HA callout is not enabled */ + return; + + sprintf(buf, "%d", arg3); + + pid = fork(); + switch (pid) { + case 0: execl(ha_callout_prog, ha_callout_prog, + event, arg1, arg2, + arg3 < 0 ? NULL : buf, + NULL); + perror("execl"); + exit(2); + case -1: perror("fork"); + break; + default: ret = waitpid(pid, NULL, 0); + } + +#ifdef dprintf + dprintf(N_DEBUG, "ha callout returned %d\n", WEXITSTATUS(ret)); +#else + xlog(D_GENERAL, "ha callout returned %d\n", WEXITSTATUS(ret)); +#endif +} + +#endif diff -puN support/include/nfslib.h~CITI_NFS4_ALL support/include/nfslib.h --- nfs-utils-1.0.6/support/include/nfslib.h~CITI_NFS4_ALL 2004-10-27 18:02:46.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/include/nfslib.h 2004-10-27 18:02:49.000000000 -0400 @@ -23,6 +23,9 @@ #ifndef _PATH_EXPORTS #define _PATH_EXPORTS "/etc/exports" #endif +#ifndef _PATH_IDMAPDCONF +#define _PATH_IDMAPDCONF "/etc/idmapd.conf" +#endif #ifndef _PATH_XTAB #define _PATH_XTAB NFS_STATEDIR "/xtab" #endif diff -puN support/lib/Makefile~CITI_NFS4_ALL support/lib/Makefile --- nfs-utils-1.0.6/support/lib/Makefile~CITI_NFS4_ALL 2004-10-27 18:02:46.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/lib/Makefile 2004-10-27 18:02:49.000000000 -0400 @@ -1,7 +1,7 @@ include $(TOP)rules.mk -LIBS = libnfs.a libexport.a libmisc.a +LIBS = libnfs.a libexport.a libmisc.a librpc.a libgssapi.a all install:: $(LIBS) @: diff -puN support/Makefile~CITI_NFS4_ALL support/Makefile diff -puN support/nfs/cacheio.c~CITI_NFS4_ALL support/nfs/cacheio.c --- nfs-utils-1.0.6/support/nfs/cacheio.c~CITI_NFS4_ALL 2004-10-27 18:02:46.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/nfs/cacheio.c 2004-10-27 18:02:49.000000000 -0400 @@ -246,10 +246,16 @@ cache_flush(int force) int c; char stime[20]; char path[200]; + /* Note: the order of these caches is important. + * The need to be flushed in dependancy order. So + * a cache that references items in another cache, + * as nfsd.fh entries reference items in nfsd.export, + * must be flushed before the cache that it references. + */ static char *cachelist[] = { "auth.unix.ip", - "nfsd.export", "nfsd.fh", + "nfsd.export", NULL }; stb.st_mtime = time(0); diff -L support/rpc/auth_gss.c -puN /dev/null /dev/null diff -L support/rpc/authgss_prot.c -puN /dev/null /dev/null diff -L support/rpc/DISCLAIMER -puN /dev/null /dev/null diff -puN /dev/null support/rpc/include/rpc/auth_gss.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/auth_gss.h 2004-10-27 18:02:50.000000000 -0400 @@ -0,0 +1,122 @@ +/* + auth_gss.h + + Copyright (c) 2000 The Regents of the University of Michigan. + All rights reserved. + + Copyright (c) 2000 Dug Song . + All rights reserved, all wrongs reversed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef _RPC_AUTH_GSS_H +#define _RPC_AUTH_GSS_H + +#include +#include + +/* RPCSEC_GSS control procedures. */ +typedef enum { + RPCSEC_GSS_DATA = 0, + RPCSEC_GSS_INIT = 1, + RPCSEC_GSS_CONTINUE_INIT = 2, + RPCSEC_GSS_DESTROY = 3 +} rpc_gss_proc_t; + +/* RPCSEC_GSS services. */ +typedef enum { + RPCSEC_GSS_SVC_NONE = 1, + RPCSEC_GSS_SVC_INTEGRITY = 2, + RPCSEC_GSS_SVC_PRIVACY = 3 +} rpc_gss_svc_t; + +#define RPCSEC_GSS_VERSION 1 + +/* RPCSEC_GSS security triple. */ +struct rpc_gss_sec { + gss_OID mech; /* mechanism */ + gss_qop_t qop; /* quality of protection */ + rpc_gss_svc_t svc; /* service */ + gss_cred_id_t cred; /* cred handle */ + u_int req_flags; /* req flags for init_sec_context */ +}; + +/* Private data required for kernel implementation */ +struct authgss_private_data { + gss_ctx_id_t pd_ctx; /* Session context handle */ + gss_buffer_desc pd_ctx_hndl; /* Credentials context handle */ + u_int pd_seq_win; /* Sequence window */ +}; + +/* Credentials. */ +struct rpc_gss_cred { + u_int gc_v; /* version */ + rpc_gss_proc_t gc_proc; /* control procedure */ + u_int gc_seq; /* sequence number */ + rpc_gss_svc_t gc_svc; /* service */ + gss_buffer_desc gc_ctx; /* context handle */ +}; + +/* Context creation response. */ +struct rpc_gss_init_res { + gss_buffer_desc gr_ctx; /* context handle */ + u_int gr_major; /* major status */ + u_int gr_minor; /* minor status */ + u_int gr_win; /* sequence window */ + gss_buffer_desc gr_token; /* token */ +}; + +/* Maximum sequence number value. */ +#define MAXSEQ 0x80000000 + +/* Prototypes. */ +__BEGIN_DECLS +bool_t xdr_rpc_gss_cred __P((XDR *xdrs, struct rpc_gss_cred *p)); +bool_t xdr_rpc_gss_init_args __P((XDR *xdrs, gss_buffer_desc *p)); +bool_t xdr_rpc_gss_init_res __P((XDR *xdrs, struct rpc_gss_init_res *p)); +bool_t xdr_rpc_gss_data __P((XDR *xdrs, xdrproc_t xdr_func, + caddr_t xdr_ptr, gss_ctx_id_t ctx, + gss_qop_t qop, rpc_gss_svc_t svc, + u_int seq)); + +AUTH *authgss_create __P((CLIENT *, gss_name_t, + struct rpc_gss_sec *)); +AUTH *authgss_create_default __P((CLIENT *, char *, struct rpc_gss_sec *)); +bool_t authgss_service __P((AUTH *auth, int svc)); +bool_t authgss_get_private_data __P((AUTH *auth, + struct authgss_private_data *)); + + +void log_debug __P((const char *fmt, ...)); +void log_status __P((char *m, OM_uint32 major, + OM_uint32 minor)); +void log_hexdump __P((const u_char *buf, int len, int offset)); + +__END_DECLS + +#endif /* !_RPC_AUTH_GSS_H */ diff -puN /dev/null support/rpc/include/rpc/auth.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/auth.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,216 @@ +/* $OpenBSD: auth.h,v 1.2 1997/09/21 10:46:09 niklas Exp $ */ +/* $NetBSD: auth.h,v 1.7 1995/04/29 05:27:55 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth.h 1.17 88/02/08 SMI + * @(#)auth.h 2.3 88/08/07 4.0 RPCSRC + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + +#ifndef _RPC_AUTH_H +#define _RPC_AUTH_H +#include + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7, /* some unknown reason */ + /* + * RPCSEC_GSS errors + */ + RPCSEC_GSS_CREDPROBLEM = 13, + RPCSEC_GSS_CTXPROBLEM = 14 +}; + +typedef u_int32_t u_int32; /* 32-bit unsigned integers */ + +union des_block { + struct { + u_int32 high; + u_int32 low; + } key; + char c[8]; +}; +typedef union des_block des_block; +__BEGIN_DECLS +extern bool_t xdr_des_block __P((XDR *, des_block *)); +__END_DECLS + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct __rpc_auth { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf) __P((struct __rpc_auth *)); + /* nextverf & serialize */ + int (*ah_marshal) __P((struct __rpc_auth *, XDR *)); + /* validate verifier */ + int (*ah_validate) __P((struct __rpc_auth *, + struct opaque_auth *)); + /* refresh credentials */ + int (*ah_refresh) __P((struct __rpc_auth *)); + /* destroy this structure */ + void (*ah_destroy) __P((struct __rpc_auth *)); + /* encode data for wire */ + int (*ah_wrap) __P((struct __rpc_auth *, XDR *, xdrproc_t, caddr_t)); + /* decode data for wire */ + int (*ah_unwrap) __P((struct __rpc_auth *, XDR *, xdrproc_t, caddr_t)); + + } *ah_ops; + caddr_t ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + +#define AUTH_WRAP(auth, xdrs, xfunc, xwhere) \ + ((*((auth)->ah_ops->ah_wrap))(auth, xdrs, \ + xfunc, xwhere)) +#define auth_wrap(auth, xdrs, xfunc, xwhere) \ + ((*((auth)->ah_ops->ah_wrap))(auth, xdrs, \ + xfunc, xwhere)) + +#define AUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ + ((*((auth)->ah_ops->ah_unwrap))(auth, xdrs, \ + xfunc, xwhere)) +#define auth_unwrap(auth, xdrs, xfunc, xwhere) \ + ((*((auth)->ah_ops->ah_unwrap))(auth, xdrs, \ + xfunc, xwhere)) + + +extern struct opaque_auth _null_auth; + +/* + * Any style authentication. These routines can be used by any + * authentication style that does not use the wrap/unwrap functions. + */ +int authany_wrap(), authany_unwrap(); + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * Unix style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * int uid; + * int gid; + * int len; + * int *aup_gids; + */ +__BEGIN_DECLS +struct sockaddr_in; +extern AUTH *authunix_create __P((char *, int, int, int, int *)); +extern AUTH *authunix_create_default __P((void)); +extern AUTH *authnone_create __P((void)); +extern AUTH *authdes_create __P((char *, u_int, + struct sockaddr_in *, des_block *)); +extern bool_t xdr_opaque_auth __P((XDR *, struct opaque_auth *)); +__END_DECLS + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ +#define RPCSEC_GSS 6 /* RPCSEC_GSS */ + +#endif /* !_RPC_AUTH_H */ diff -puN /dev/null support/rpc/include/rpc/auth_unix.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/auth_unix.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,84 @@ +/* $OpenBSD: auth_unix.h,v 1.2 1997/09/21 10:46:09 niklas Exp $ */ +/* $NetBSD: auth_unix.h,v 1.4 1994/10/26 00:56:56 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth_unix.h 1.8 88/02/08 SMI + * @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC + */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + */ + +#ifndef _RPC_AUTH_UNIX_H +#define _RPC_AUTH_UNIX_H +#include + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* gids compose part of a credential; there may not be more than 16 of them */ +#define NGRPS 16 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + int aup_uid; + int aup_gid; + u_int aup_len; + int *aup_gids; +}; + +__BEGIN_DECLS +extern bool_t xdr_authunix_parms __P((XDR *, struct authunix_parms *)); +__END_DECLS + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; + +#endif /* !_RPC_AUTH_UNIX_H */ diff -puN /dev/null support/rpc/include/rpc/clnt.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/clnt.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,373 @@ +/* $OpenBSD: clnt.h,v 1.4 1998/03/19 00:27:17 millert Exp $ */ +/* $NetBSD: clnt.h,v 1.6 1995/04/29 05:27:58 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)clnt.h 1.31 88/02/08 SMI + * @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC + */ + +/* + * clnt.h - Client side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_CLNT_H_ +#define _RPC_CLNT_H_ +#include + +/* + * Rpc calls return an enum clnt_stat. This should be looked at more, + * since each implementation is required to live with this (implementation + * independent) list of errors. + */ +enum clnt_stat { + RPC_SUCCESS=0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS=1, /* can't encode arguments */ + RPC_CANTDECODERES=2, /* can't decode results */ + RPC_CANTSEND=3, /* failure in sending call */ + RPC_CANTRECV=4, /* failure in receiving result */ + RPC_TIMEDOUT=5, /* call timed out */ + /* + * remote errors + */ + RPC_VERSMISMATCH=6, /* rpc versions not compatible */ + RPC_AUTHERROR=7, /* authentication error */ + RPC_PROGUNAVAIL=8, /* program not available */ + RPC_PROGVERSMISMATCH=9, /* program version mismatched */ + RPC_PROCUNAVAIL=10, /* procedure unavailable */ + RPC_CANTDECODEARGS=11, /* decode arguments error */ + RPC_SYSTEMERROR=12, /* generic "other problem" */ + + /* + * callrpc & clnt_create errors + */ + RPC_UNKNOWNHOST=13, /* unknown host name */ + RPC_UNKNOWNPROTO=17, /* unkown protocol */ + + /* + * _ create errors + */ + RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ + RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ + /* + * unspecified error + */ + RPC_FAILED=16 +}; + + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* realated system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + u_int32_t low; /* lowest verion supported */ + u_int32_t high; /* highest verion supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + int32_t s1; + int32_t s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations, see e.g. rpc_udp.c. + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +typedef struct __rpc_client { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + /* call remote procedure */ + enum clnt_stat (*cl_call) __P((struct __rpc_client *, + u_long, xdrproc_t, caddr_t, xdrproc_t, + caddr_t, struct timeval)); + /* abort a call */ + void (*cl_abort) __P((struct __rpc_client *)); + /* get specific error code */ + void (*cl_geterr) __P((struct __rpc_client *, + struct rpc_err *)); + /* frees results */ + bool_t (*cl_freeres) __P((struct __rpc_client *, + xdrproc_t, caddr_t)); + /* destroy this structure */ + void (*cl_destroy) __P((struct __rpc_client *)); + /* the ioctl() of rpc */ + bool_t (*cl_control) __P((struct __rpc_client *, u_int, + void *)); + } *cl_ops; + caddr_t cl_private; /* private stuff */ +} CLIENT; + + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * u_long proc; + * xdrproc_t xargs; + * caddr_t argsp; + * xdrproc_t xres; + * caddr_t resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \ + xres, (caddr_t)resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \ + xres, (caddr_t)resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * caddr_t resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +/* + * udp only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessable on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((u_long)1) +#define RPCTEST_VERSION ((u_long)1) +#define RPCTEST_NULL_PROC ((u_long)2) +#define RPCTEST_NULL_BATCH_PROC ((u_long)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((u_int)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clntraw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +__BEGIN_DECLS +extern CLIENT *clntraw_create __P((u_long, u_long)); +__END_DECLS + + +/* + * Generic client creation routine. Supported protocols are "udp" and "tcp" + * CLIENT * + * clnt_create(host, prog, vers, prot); + * char *host; -- hostname + * u_long prog; -- program number + * u_long vers; -- version number + * char *prot; -- protocol + */ +__BEGIN_DECLS +extern CLIENT *clnt_create __P((char *, u_long, u_long, char *)); +__END_DECLS + + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clnttcp_create __P((struct sockaddr_in *, + u_long, + u_long, + int *, + u_int, + u_int)); +__END_DECLS + + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clntudp_create __P((struct sockaddr_in *, + u_long, + u_long, + struct timeval, + int *)); +extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *, + u_long, + u_long, + struct timeval, + int *, + u_int, + u_int)); +__END_DECLS + + +/* + * Print why creation failed + */ +__BEGIN_DECLS +extern void clnt_pcreateerror __P((char *)); /* stderr */ +extern char *clnt_spcreateerror __P((char *)); /* string */ +__END_DECLS + +/* + * Like clnt_perror(), but is more verbose in its output + */ +__BEGIN_DECLS +extern void clnt_perrno __P((enum clnt_stat)); /* stderr */ +extern char *clnt_sperrno __P((enum clnt_stat)); /* string */ +__END_DECLS + +/* + * Print an English error message, given the client error code + */ +__BEGIN_DECLS +extern void clnt_perror __P((CLIENT *, char *)); /* stderr */ +extern char *clnt_sperror __P((CLIENT *, char *)); /* string */ +__END_DECLS + + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +extern struct rpc_createerr rpc_createerr; + + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +#endif /* !_RPC_CLNT_H */ diff -puN /dev/null support/rpc/include/rpc/pmap_clnt.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/pmap_clnt.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,87 @@ +/* $OpenBSD: pmap_clnt.h,v 1.3 1998/08/29 18:57:14 deraadt Exp $ */ +/* $NetBSD: pmap_clnt.h,v 1.5 1994/12/04 01:12:42 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI + * @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +#ifndef _RPC_PMAPCLNT_H +#define _RPC_PMAPCLNT_H +#include + +__BEGIN_DECLS +extern bool_t pmap_set __P((u_long, u_long, u_int, int)); +extern bool_t pmap_unset __P((u_long, u_long)); +extern struct pmaplist *pmap_getmaps __P((struct sockaddr_in *)); +extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *, + u_long, u_long, u_long, + xdrproc_t, caddr_t, + xdrproc_t, caddr_t, + struct timeval, u_long *)); +extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long, + xdrproc_t, char *, + xdrproc_t, char *, + bool_t (*) __P((caddr_t, + struct sockaddr_in *)))); +extern u_short pmap_getport __P((struct sockaddr_in *, + u_long, u_long, u_int)); +__END_DECLS + +#endif /* !_RPC_PMAPCLNT_H */ diff -puN /dev/null support/rpc/include/rpc/pmap_prot.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/pmap_prot.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,106 @@ +/* $OpenBSD: pmap_prot.h,v 1.3 1998/02/10 06:25:32 deraadt Exp $ */ +/* $NetBSD: pmap_prot.h,v 1.4 1994/10/26 00:57:00 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_prot.h 1.14 88/02/08 SMI + * @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (unsigned long). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned int, unsigned int, unsigned int, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#ifndef _RPC_PMAPPROT_H +#define _RPC_PMAPPROT_H +#include + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + unsigned long pm_prog; + unsigned long pm_vers; + unsigned long pm_prot; + unsigned long pm_port; +}; + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +__BEGIN_DECLS +extern bool_t xdr_pmap __P((XDR *, struct pmap *)); +extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **)); +__END_DECLS + +#endif /* !_RPC_PMAPPROT_H */ diff -puN /dev/null support/rpc/include/rpc/pmap_rmt.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/pmap_rmt.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,65 @@ +/* $OpenBSD: pmap_rmt.h,v 1.2 1997/09/21 10:46:13 niklas Exp $ */ +/* $NetBSD: pmap_rmt.h,v 1.4 1994/10/26 00:57:01 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI + * @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +#ifndef _RPC_PMAPRMT_H +#define _RPC_PMAPRMT_H +#include + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +__BEGIN_DECLS +extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *)); +extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *)); +__END_DECLS + +#endif /* !_RPC_PMAPRMT_H */ diff -puN /dev/null support/rpc/include/rpc/rpc_des.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/rpc_des.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,133 @@ +/* $OpenBSD: rpc_des.h,v 1.3 1998/02/10 06:25:33 deraadt Exp $ */ + +/* crypto/des/rpc_des.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@mincom.oz.au). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@mincom.oz.au). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@mincom.oz.au)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@mincom.oz.au)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Generic DES driver interface + * Keep this file hardware independent! + * Copyright (c) 1986 by Sun Microsystems, Inc. + */ + +#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ +#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ + +#ifdef HEADER_DES_H +#undef ENCRYPT +#undef DECRYPT +#endif + +enum desdir { ENCRYPT, DECRYPT }; +enum desmode { CBC, ECB }; + +/* + * parameters to ioctl call + */ +struct desparams { + unsigned char des_key[8]; /* key (with low bit parity) */ + enum desdir des_dir; /* direction */ + enum desmode des_mode; /* mode */ + unsigned char des_ivec[8]; /* input vector */ + unsigned int des_len; /* number of bytes to crypt */ + union { + unsigned char UDES_data[DES_QUICKLEN]; + unsigned char *UDES_buf; + } UDES; +# define des_data UDES.UDES_data /* direct data here if quick */ +# define des_buf UDES.UDES_buf /* otherwise, pointer to data */ +}; + +/* + * Encrypt an arbitrary sized buffer + */ +#define DESIOCBLOCK _IOWR(d, 6, struct desparams) + +/* + * Encrypt of small amount of data, quickly + */ +#define DESIOCQUICK _IOWR(d, 7, struct desparams) + diff -puN /dev/null support/rpc/include/rpc/rpc.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/rpc.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,109 @@ +/* $OpenBSD: rpc.h,v 1.7 1998/12/20 23:43:18 millert Exp $ */ +/* $NetBSD: rpc.h,v 1.5 1994/12/04 01:15:30 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc.h 1.9 88/02/08 SMI + * @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC + */ + +/* + * rpc.h, Just includes the billions of rpc header files necessary to + * do remote procedure calling. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ +#ifndef _RPC_RPC_H +#define _RPC_RPC_H + +#include /* some typedefs */ +#include + +/* external data representation interfaces */ +#include /* generic (de)serializer */ + +/* Client side only authentication */ +#include /* generic authenticator (client side) */ + +/* Client side (mostly) remote procedure call */ +#include /* generic rpc stuff */ + +/* Client side (mostly) pmap functions */ +#include /* generic pmap stuff */ + +/* semi-private protocol headers */ +#include /* protocol for rpc messages */ +#include /* protocol for unix style cred */ +#include "auth_gss.h" /* RPCSEC_GSS */ + +/* + * Uncomment-out the next line if you are building the rpc library with + * DES Authentication (see the README file in the secure_rpc/ directory). + */ +#ifdef notdef +#include /* protocol for des style cred */ +#endif + +/* Server side only remote procedure callee */ +#include /* service side authenticator */ +#include /* service manager and multiplexer */ + +/* + * COMMENT OUT THE NEXT INCLUDE (or add to the #ifndef) IF RUNNING ON + * A VERSION OF UNIX THAT USES SUN'S NFS SOURCE. These systems will + * already have the structures defined by included in . + */ +/* routines for parsing /etc/rpc */ +#ifdef __linux__ +#include +#else +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; + +__BEGIN_DECLS +extern struct rpcent *getrpcbyname __P((char *)); +extern struct rpcent *getrpcbynumber __P((int)); +extern struct rpcent *getrpcent __P((void)); +extern void setrpcent __P((int)); +extern void endrpcent __P((void)); + +extern int get_myaddress __P((struct sockaddr_in *)); +extern int registerrpc __P((int, int, int, char *(*) __P((char [UDPMSGSIZE])), + xdrproc_t, xdrproc_t)); +extern int callrpc __P((char *, int, int, int, xdrproc_t, char *, + xdrproc_t , char *)); +extern int getrpcport __P((char *, int, int, int)); + +__END_DECLS +#endif /* __linux__ */ + +#endif /* !_RPC_RPC_H */ diff -puN /dev/null support/rpc/include/rpc/rpc_msg.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/rpc_msg.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,197 @@ +/* $OpenBSD: rpc_msg.h,v 1.2 1997/09/21 10:46:15 niklas Exp $ */ +/* $NetBSD: rpc_msg.h,v 1.5 1995/04/29 05:28:00 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_msg.h 1.7 86/07/16 SMI + * @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC + */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_RPCMSG_H +#define _RPC_RPCMSG_H + +#define RPC_MSG_VERSION ((u_long) 2) +#define RPC_SERVICE_PORT ((u_short) 2048) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum msg_type { + CALL=0, + REPLY=1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS=0, + PROG_UNAVAIL=1, + PROG_MISMATCH=2, + PROC_UNAVAIL=3, + GARBAGE_ARGS=4, + SYSTEM_ERR=5 +}; + +enum reject_stat { + RPC_MISMATCH=0, + AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was accepted by the server. + * Note: there could be an error even though the request was + * accepted. + */ +struct accepted_reply { + struct opaque_auth ar_verf; + enum accept_stat ar_stat; + union { + struct { + u_int32_t low; + u_int32_t high; + } AR_versions; + struct { + caddr_t where; + xdrproc_t proc; + } AR_results; + /* and many other null cases */ + } ru; +#define ar_results ru.AR_results +#define ar_vers ru.AR_versions +}; + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct rejected_reply { + enum reject_stat rj_stat; + union { + struct { + u_int32_t low; + u_int32_t high; + } RJ_versions; + enum auth_stat RJ_why; /* why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct reply_body { + enum reply_stat rp_stat; + union { + struct accepted_reply RP_ar; + struct rejected_reply RP_dr; + } ru; +#define rp_acpt ru.RP_ar +#define rp_rjct ru.RP_dr +}; + +/* + * Body of an rpc request call. + */ +struct call_body { + u_int32_t cb_rpcvers; /* must be equal to two */ + u_int32_t cb_prog; + u_int32_t cb_vers; + u_int32_t cb_proc; + struct opaque_auth cb_cred; + struct opaque_auth cb_verf; /* protocol specific - provided by client */ +}; + +/* + * The rpc message + */ +struct rpc_msg { + u_int32_t rm_xid; + enum msg_type rm_direction; + union { + struct call_body RM_cmb; + struct reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr + +__BEGIN_DECLS +/* + * XDR routine to handle a rpc message. + * xdr_callmsg(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callmsg __P((XDR *, struct rpc_msg *)); + +/* + * XDR routine to pre-serialize the static part of a rpc message. + * xdr_callhdr(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *)); + +/* + * XDR routine to handle a rpc reply. + * xdr_replymsg(xdrs, rmsg) + * XDR *xdrs; + * struct rpc_msg *rmsg; + */ +extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *)); + +/* + * Fills in the error part of a reply message. + * _seterr_reply(msg, error) + * struct rpc_msg *msg; + * struct rpc_err *error; + */ +extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *)); +__END_DECLS + +#endif /* !_RPC_RPCMSG_H */ diff -puN /dev/null support/rpc/include/rpc/svc_auth.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/svc_auth.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,81 @@ +/* $OpenBSD: svc_auth.h,v 1.2 1997/09/21 10:46:16 niklas Exp $ */ +/* $NetBSD: svc_auth.h,v 1.4 1994/10/26 00:57:07 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)svc_auth.h 1.6 86/07/16 SMI + * @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC + */ + +/* + * svc_auth.h, Service side of rpc authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_SVCAUTH_H +#define _RPC_SVCAUTH_H + +/* + * Interface to server-side authentication flavors. + */ +typedef struct { + struct svc_auth_ops { + int (*svc_ah_wrap)(); + int (*svc_ah_unwrap)(); + int (*svc_ah_destroy)(); + } *svc_ah_ops; + caddr_t svc_ah_private; +} SVCAUTH; + +#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \ + ((*((auth)->svc_ah_ops->svc_ah_wrap))(auth, xdrs, xfunc, xwhere)) +#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ + ((*((auth)->svc_ah_ops->svc_ah_unwrap))(auth, xdrs, xfunc, xwhere)) +#define SVCAUTH_DESTROY(auth) \ + ((*((auth)->svc_ah_ops->svc_ah_destroy))(auth)) + +/* + * Approved way of getting principal of caller + */ +char *svcauth_gss_get_principal __P((SVCAUTH *auth)); + +/* + * Approved way of setting server principal + */ +bool_t svcauth_gss_set_svc_name __P((gss_name_t name)); + +/* + * Server side authenticator + */ +__BEGIN_DECLS +extern enum auth_stat _authenticate(); +__END_DECLS + +#endif /* !_RPC_SVCAUTH_H */ diff -puN /dev/null support/rpc/include/rpc/svc.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/svc.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,334 @@ +/* $OpenBSD: svc.h,v 1.2 1997/09/21 10:46:16 niklas Exp $ */ +/* $NetBSD: svc.h,v 1.9 1995/04/29 05:28:01 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)svc.h 1.20 88/02/08 SMI + * @(#)svc.h 2.2 88/07/29 4.0 RPCSRC + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_SVC_H +#define _RPC_SVC_H +#include + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct __rpc_svcxprt { + int xp_sock; + u_short xp_port; /* associated port number */ + struct xp_ops { + /* receive incomming requests */ + bool_t (*xp_recv) __P((struct __rpc_svcxprt *, + struct rpc_msg *)); + /* get transport status */ + enum xprt_stat (*xp_stat) __P((struct __rpc_svcxprt *)); + /* get arguments */ + bool_t (*xp_getargs) __P((struct __rpc_svcxprt *, xdrproc_t, + caddr_t)); + /* send reply */ + bool_t (*xp_reply) __P((struct __rpc_svcxprt *, + struct rpc_msg *)); + /* free mem allocated for args */ + bool_t (*xp_freeargs) __P((struct __rpc_svcxprt *, xdrproc_t, + caddr_t)); + /* destroy this struct */ + void (*xp_destroy) __P((struct __rpc_svcxprt *)); + } *xp_ops; + int xp_addrlen; /* length of remote address */ + struct sockaddr_in xp_raddr; /* remote address */ + struct opaque_auth xp_verf; /* raw response verifier */ + SVCAUTH *xp_auth; /* auth handle of current req */ + caddr_t xp_p1; /* private */ + caddr_t xp_p2; /* private */ +} SVCXPRT; + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * caddr_t argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + + +/* + * Service request + */ +struct svc_req { + u_int32_t rq_prog; /* service program number */ + u_int32_t rq_vers; /* service protocol version */ + u_int32_t rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + caddr_t rq_clntcred; /* read only cooked cred */ + caddr_t rq_clntname; /* read only client name */ + caddr_t rq_svcname; /* read only cooked service cred */ + SVCXPRT *rq_xprt; /* associated transport */ + + /* The request's auth flavor *should* be here, but the svc_req */ + /* isn't passed around everywhere it is necessary. The */ + /* transport *is* passed around, so the auth flavor it stored */ + /* there. This means that the transport must be single */ + /* threaded, but other parts of SunRPC already require that. */ + /*SVCAUTH *rq_auth; associated auth flavor */ +}; + + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; like TCP or UDP, zero means do not register + */ +__BEGIN_DECLS +extern bool_t svc_register __P((SVCXPRT *, u_long, u_long, + void (*) __P((struct svc_req *, SVCXPRT *)), int)); +__END_DECLS + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +__BEGIN_DECLS +extern void svc_unregister __P((u_long, u_long)); +__END_DECLS + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +__BEGIN_DECLS +extern void xprt_register __P((SVCXPRT *)); +__END_DECLS + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +__BEGIN_DECLS +extern void xprt_unregister __P((SVCXPRT *)); +__END_DECLS + + + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +__BEGIN_DECLS +extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *)); +extern void svcerr_decode __P((SVCXPRT *)); +extern void svcerr_weakauth __P((SVCXPRT *)); +extern void svcerr_noproc __P((SVCXPRT *)); +extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long)); +extern void svcerr_auth __P((SVCXPRT *, enum auth_stat)); +extern void svcerr_noprog __P((SVCXPRT *)); +extern void svcerr_systemerr __P((SVCXPRT *)); +__END_DECLS + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existant) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +extern int svc_maxfd; +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +extern void rpctest_service(); /* XXX relic? */ + +__BEGIN_DECLS +extern void svc_getreq __P((int)); +extern void svc_getreqset __P((fd_set *)); +extern void svc_getreqset2 __P((fd_set *, int)); +extern void svc_run __P((void)); +__END_DECLS + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 + +/* + * These are the existing service side transport implementations + */ + +/* + * Memory based rpc for testing and timing. + */ +__BEGIN_DECLS +extern SVCXPRT *svcraw_create __P((void)); +__END_DECLS + + +/* + * Udp based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svcudp_create __P((int)); +extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int)); +__END_DECLS + + +/* + * Tcp based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svctcp_create __P((int, u_int, u_int)); +__END_DECLS + +/* + * Fd based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svcfd_create __P((int, u_int, u_int)); +__END_DECLS + +#endif /* !_RPC_SVC_H */ diff -puN /dev/null support/rpc/include/rpc/types.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/types.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,66 @@ +/* $OpenBSD: types.h,v 1.2 1997/09/21 10:46:17 niklas Exp $ */ +/* $NetBSD: types.h,v 1.8 1995/04/29 05:28:05 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)types.h 1.18 87/07/24 SMI + * @(#)types.h 2.3 88/08/15 4.0 RPCSRC + */ + +/* + * Rpc additions to + */ +#ifndef _RPC_TYPES_H +#define _RPC_TYPES_H + +#define bool_t int32_t +#define enum_t int32_t +#define __dontcare__ -1 + +#ifndef FALSE +# define FALSE (0) +#endif +#ifndef TRUE +# define TRUE (1) +#endif +#ifndef NULL +# define NULL 0 +#endif + +#define mem_alloc(bsize) malloc(bsize) +#define mem_free(ptr, bsize) free(ptr) + +#ifndef makedev /* ie, we haven't already included it */ +#include +#endif +#include +#include +#include + +#endif /* !_RPC_TYPES_H */ diff -puN /dev/null support/rpc/include/rpc/xdr.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/support/rpc/include/rpc/xdr.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,310 @@ +/* $OpenBSD: xdr.h,v 1.2 1997/09/21 10:46:18 niklas Exp $ */ +/* $NetBSD: xdr.h,v 1.7 1995/04/29 05:28:06 cgd Exp $ */ + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)xdr.h 1.19 87/04/22 SMI + * @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC + */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_XDR_H +#define _RPC_XDR_H +#include +#include + +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * Xdr operations. XDR_ENCODE causes the type to be encoded into the + * stream. XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; + +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ + * BYTES_PER_XDR_UNIT) + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the paticular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular impelementation. + */ +typedef struct __rpc_xdr { + enum xdr_op x_op; /* operation; fast additional param */ + struct xdr_ops { + /* get a long from underlying stream */ + bool_t (*x_getlong) __P((struct __rpc_xdr *, long *)); + /* put a long to " */ + bool_t (*x_putlong) __P((struct __rpc_xdr *, long *)); + /* get some bytes from " */ + bool_t (*x_getbytes) __P((struct __rpc_xdr *, caddr_t, u_int)); + /* put some bytes to " */ + bool_t (*x_putbytes) __P((struct __rpc_xdr *, caddr_t, u_int)); + /* returns bytes off from beginning */ + u_int (*x_getpostn) __P((struct __rpc_xdr *)); + /* lets you reposition the stream */ + bool_t (*x_setpostn) __P((struct __rpc_xdr *, u_int)); + /* buf quick ptr to buffered data */ + int32_t *(*x_inline) __P((struct __rpc_xdr *, u_int)); + /* free privates of this xdr_stream */ + void (*x_destroy) __P((struct __rpc_xdr *)); + } *x_ops; + caddr_t x_public; /* users' data */ + caddr_t x_private; /* pointer to private data */ + caddr_t x_base; /* private used for position info */ + int x_handy; /* extra private word */ +} XDR; + +/* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + * + * XXX can't actually prototype it, because some take three args!!! + */ +typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */)); + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * caddr_t addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * a entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitve data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) + +/* + * These are the "generic" xdr routines. + */ +__BEGIN_DECLS +extern bool_t xdr_void __P((void)); +extern bool_t xdr_int __P((XDR *, int *)); +extern bool_t xdr_u_int __P((XDR *, u_int *)); +extern bool_t xdr_long __P((XDR *, long *)); +extern bool_t xdr_u_long __P((XDR *, u_long *)); +extern bool_t xdr_short __P((XDR *, short *)); +extern bool_t xdr_u_short __P((XDR *, u_short *)); +extern bool_t xdr_int16_t __P((XDR *, int16_t *)); +extern bool_t xdr_u_int16_t __P((XDR *, u_int16_t *)); +extern bool_t xdr_int32_t __P((XDR *, int32_t *)); +extern bool_t xdr_u_int32_t __P((XDR *, u_int32_t *)); +extern bool_t xdr_bool __P((XDR *, bool_t *)); +extern bool_t xdr_enum __P((XDR *, enum_t *)); +extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t)); +extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int)); +extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int)); +extern bool_t xdr_string __P((XDR *, char **, u_int)); +extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t)); +extern bool_t xdr_char __P((XDR *, char *)); +extern bool_t xdr_u_char __P((XDR *, u_char *)); +extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t)); +extern bool_t xdr_float __P((XDR *, float *)); +extern bool_t xdr_double __P((XDR *, double *)); +extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t)); +extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t)); +extern bool_t xdr_wrapstring __P((XDR *, char **)); +extern void xdr_free __P((xdrproc_t, char *)); +__END_DECLS + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ + +#define MAX_NETOBJ_SZ 2048 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +extern bool_t xdr_netobj __P((XDR *, struct netobj *)); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +__BEGIN_DECLS +/* XDR using memory buffers */ +extern void xdrmem_create __P((XDR *, char *, u_int, enum xdr_op)); + +#ifdef _STDIO_H_ +/* XDR using stdio library */ +extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op)); +#endif + +/* XDR pseudo records for tcp */ +extern void xdrrec_create __P((XDR *, u_int, u_int, char *, + int (*) __P((caddr_t, caddr_t, int)), + int (*) __P((caddr_t, caddr_t, int)))); + +/* make end of xdr record */ +extern bool_t xdrrec_endofrecord __P((XDR *, int)); + +/* move to beginning of next record */ +extern bool_t xdrrec_skiprecord __P((XDR *)); + +/* true if no more input */ +extern bool_t xdrrec_eof __P((XDR *)); +__END_DECLS + +#endif /* !_RPC_XDR_H */ diff -L support/rpc/Makefile -puN /dev/null /dev/null diff -L support/rpc/README -puN /dev/null /dev/null diff -L support/rpc/rpc_commondata.c -puN /dev/null /dev/null diff -L support/rpc/svc_auth.c -puN /dev/null /dev/null diff -L support/rpc/svc_auth_gss.c -puN /dev/null /dev/null diff -L support/rpc/svc_auth_none.c -puN /dev/null /dev/null diff -L support/rpc/svc_auth_unix.c -puN /dev/null /dev/null diff -L support/rpc/svc.c -puN /dev/null /dev/null diff -L support/rpc/svc_raw.c -puN /dev/null /dev/null diff -L support/rpc/svc_run.c -puN /dev/null /dev/null diff -L support/rpc/svc_simple.c -puN /dev/null /dev/null diff -L support/rpc/svc_tcp.c -puN /dev/null /dev/null diff -L support/rpc/svc_udp.c -puN /dev/null /dev/null diff -puN utils/exportfs/exportfs.c~CITI_NFS4_ALL utils/exportfs/exportfs.c --- nfs-utils-1.0.6/utils/exportfs/exportfs.c~CITI_NFS4_ALL 2004-10-27 18:02:47.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/exportfs/exportfs.c 2004-10-27 18:02:49.000000000 -0400 @@ -130,7 +130,8 @@ main(int argc, char **argv) if (!f_export) for (i = optind ; i < argc ; i++) unexportfs(argv[i], f_verbose); - rmtab_read(); + if (!new_cache) + rmtab_read(); } if (!new_cache) { xtab_mount_read(); @@ -145,10 +146,43 @@ main(int argc, char **argv) return export_errno; } +static void +exports_update_one(nfs_export *exp, int verbose) +{ + /* check mountpoint option */ + if (exp->m_mayexport && + exp->m_export.e_mountpoint && + !is_mountpoint(exp->m_export.e_mountpoint[0]? + exp->m_export.e_mountpoint: + exp->m_export.e_path)) { + printf("%s not exported as %s not a mountpoint.\n", + exp->m_export.e_path, exp->m_export.e_mountpoint); + exp->m_mayexport = 0; + } + if (exp->m_mayexport && ((exp->m_exported<1) || exp->m_changed)) { + if (verbose) + printf("%sexporting %s:%s to kernel\n", + exp->m_exported ?"re":"", + exp->m_client->m_hostname, + exp->m_export.e_path); + if (!export_export(exp)) + error(exp, errno); + } + if (exp->m_exported && ! exp->m_mayexport) { + if (verbose) + printf("unexporting %s:%s from kernel\n", + exp->m_client->m_hostname, + exp->m_export.e_path); + if (!export_unexport(exp)) + error(exp, errno); + } +} + + /* we synchronise intention with reality. * entries with m_mayexport get exported * entries with m_exported but not m_mayexport get unexported - * looking at m_client->m_type == MCL_FQDN only + * looking at m_client->m_type == MCL_FQDN and m_client->m_type == MCL_GSS only */ static void exports_update(int verbose) @@ -156,33 +190,10 @@ exports_update(int verbose) nfs_export *exp; for (exp = exportlist[MCL_FQDN]; exp; exp=exp->m_next) { - /* check mountpoint option */ - if (exp->m_mayexport && - exp->m_export.e_mountpoint && - !is_mountpoint(exp->m_export.e_mountpoint[0]? - exp->m_export.e_mountpoint: - exp->m_export.e_path)) { - printf("%s not exported as %s not a mountpoint.\n", - exp->m_export.e_path, exp->m_export.e_mountpoint); - exp->m_mayexport = 0; - } - if (exp->m_mayexport && ((exp->m_exported<1) || exp->m_changed)) { - if (verbose) - printf("%sexporting %s:%s to kernel\n", - exp->m_exported ?"re":"", - exp->m_client->m_hostname, - exp->m_export.e_path); - if (!export_export(exp)) - error(exp, errno); - } - if (exp->m_exported && ! exp->m_mayexport) { - if (verbose) - printf("unexporting %s:%s from kernel\n", - exp->m_client->m_hostname, - exp->m_export.e_path); - if (!export_unexport(exp)) - error(exp, errno); - } + exports_update_one(exp, verbose); + } + for (exp = exportlist[MCL_GSS]; exp; exp=exp->m_next) { + exports_update_one(exp, verbose); } } diff -puN utils/exportfs/exports.man~CITI_NFS4_ALL utils/exportfs/exports.man --- nfs-utils-1.0.6/utils/exportfs/exports.man~CITI_NFS4_ALL 2004-10-27 18:02:47.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/exportfs/exports.man 2004-10-27 18:02:49.000000000 -0400 @@ -79,6 +79,11 @@ may work by accident when reverse DNS lo '''.B \-\-public\-root '''option. Multiple specifications of a public root will be ignored. .PP +.SS RPCSEC_GSS security +To restrict access to an export using rpcsec_gss security, use the special +string "gss/krb5" as the client. It is not possible to simultaneously require +rpcsec_gss and to make requirements on the IP address of the client. +.PP .SS General Options .IR exportfs understands the following export options: @@ -256,6 +261,28 @@ If a path is given (e.g. then the nominted path must be a mountpoint for the exportpoint to be exported. +.TP +.IR fsid= num +This option forces the filesystem identification portion of the file +handle and file attributes used on the wire to be +.I num +instead of a number derived from the major and minor number of the +block device on which the filesystem is mounted. Any 32 bit number +can be used, but it must be unique amongst all the exported filesystems. + +This can be useful for NFS failover, to ensure that both servers of +the failover pair use the same NFS file handles for the shared filesystem +thus avoiding stale file handles after failover. + +Some Linux filesystems are not mounted on a block device; exporting +these via NFS requires the use of the +.I fsid +option (although that may still not be enough). + +The value 0 has a special meaning when use with NFSv4. NFSv4 has a +concept of a root of the overall exported filesystem. The export point +exported with fsid=0 will be used as this root. + .SS User ID Mapping .PP .I nfsd diff -puN /dev/null utils/gssd/context.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/context.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,467 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" +#include +#include +#include +#ifdef HAVE_KRB5 +#include +#endif +#include +#include +#include "gss_util.h" +#include "gss_oids.h" +#include "err_util.h" +#include "context.h" + +/* spkm3 seems to actually want it this big, yipes. */ +#define MAX_CTX_LEN 4096 + +#ifdef HAVE_KRB5 /* MIT Kerberos */ + +#ifdef HAVE_LUCID_CONTEXT_SUPPORT + +/* Don't use the private structure, use the exported lucid structure */ +#include +#include + +#elif (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? */ + +typedef struct _krb5_gss_ctx_id_rec { + unsigned int initiate : 1; /* nonzero if initiating, zero if accepting */ + unsigned int established : 1; + unsigned int big_endian : 1; + unsigned int have_acceptor_subkey : 1; + unsigned int seed_init : 1; /* XXX tested but never actually set */ +#ifdef CFX_EXERCISE + unsigned int testing_unknown_tokid : 1; /* for testing only */ +#endif + OM_uint32 gss_flags; + unsigned char seed[16]; + krb5_principal here; + krb5_principal there; + krb5_keyblock *subkey; + int signalg; + size_t cksum_size; + int sealalg; + krb5_keyblock *enc; + krb5_keyblock *seq; + krb5_timestamp endtime; + krb5_flags krb_flags; + /* XXX these used to be signed. the old spec is inspecific, and + the new spec specifies unsigned. I don't believe that the change + affects the wire encoding. */ + uint64_t seq_send; /* gssint_uint64 */ + uint64_t seq_recv; /* gssint_uint64 */ + void *seqstate; + krb5_auth_context auth_context; + gss_buffer_desc *mech_used; /* gss_OID_desc */ + /* Protocol spec revision + 0 => RFC 1964 with 3DES and RC4 enhancements + 1 => draft-ietf-krb-wg-gssapi-cfx-01 + No others defined so far. */ + int proto; + krb5_cksumtype cksumtype; /* for "main" subkey */ + krb5_keyblock *acceptor_subkey; /* CFX only */ + krb5_cksumtype acceptor_subkey_cksumtype; +#ifdef CFX_EXERCISE + gss_buffer_desc init_token; +#endif +} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; + +#else /* KRB5_VERSION */ + +typedef struct _krb5_gss_ctx_id_rec { + int initiate; + u_int32_t gss_flags; + int seed_init; + unsigned char seed[16]; + krb5_principal here; + krb5_principal there; + krb5_keyblock *subkey; + int signalg; + int cksum_size; + int sealalg; + krb5_keyblock *enc; + krb5_keyblock *seq; + krb5_timestamp endtime; + krb5_flags krb_flags; + krb5_ui_4 seq_send; + krb5_ui_4 seq_recv; + void *seqstate; + int established; + int big_endian; + krb5_auth_context auth_context; + gss_buffer_desc *mech_used; + int nctypes; + krb5_cksumtype *ctypes; +} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; + +#endif /* KRB5_VERSION */ +#endif /* HAVE_KRB5 */ + +/* XXX We have the same issue as above. We can require SPKM-3 source + * at the time we compile gssd, or copy the context structure definitions + * here. + */ + +/* structure typedefs */ + +typedef struct spkm3_ctx_id_t { + int length; + unsigned char *data; +} spkm3_ctx_id, + *spkm3_ctx_id_t; + +/* first pass at spkm3 context. will add a bunch of stuff .... */ + +typedef struct spkm3_gss_ctx_id_desc_t { + spkm3_ctx_id ctx_id; /* per spkm token contextid */ + int established; + int qop; /* negotiated qop */ + gss_OID mech_used; + OM_uint32 ret_flags; + OM_uint32 req_flags; + /* DH should be abstracted to an EVP_ struct able to hold + * various kalg results */ + /* XXX The following is defined as "DH *dh" in the original + * header we're gonna cheat and use "void *dh" here. */ + void *dh; + gss_buffer_desc share_key; + /* derived keys are result from applying the owf_alg to the + * shared key - see spkm3_derive_supkey */ + gss_buffer_desc derived_conf_key; + gss_buffer_desc derived_integ_key; + /* openssl NID's of the negotiated algorithms */ + int keyestb_alg; /* key establishment */ + int owf_alg; /* one way function */ + int intg_alg; /* integrity */ + int conf_alg; /* privacy */ + /* der encoded REQ_TOKEN reqcontets and length */ + unsigned char *der_reqcontents; + int der_req_len; +} spkm3_gss_ctx_id_desc; + + +/* adapted from mit kerberos 5 ../lib/gssapi/mechglue/mglueP.h + * this is what gets passed around when the mechglue code is enabled : */ +typedef struct gss_union_ctx_id_t { + gss_OID mech_type; + gss_ctx_id_t internal_ctx_id; +} gss_union_ctx_id_desc, *gss_union_ctx_id_t; + +#ifdef HAVE_KRB5 /* MIT Kerberos */ +#ifdef HAVE_LUCID_CONTEXT_SUPPORT /* Lucid context support */ +static int +write_lucid_keyblock(char **p, char *end, gss_krb5_lucid_key_t *key) +{ + gss_buffer_desc tmp; + + if (WRITE_BYTES(p, end, key->type)) return -1; + tmp.length = key->length; + tmp.value = key->data; + if (write_buffer(p, end, &tmp)) return -1; + return 0; +} + +#else /* lucid context support */ + +static int +write_keyblock(char **p, char *end, struct _krb5_keyblock *arg) +{ + gss_buffer_desc tmp; + + if (WRITE_BYTES(p, end, arg->enctype)) return -1; + tmp.length = arg->length; + tmp.value = arg->contents; + if (write_buffer(p, end, &tmp)) return -1; + return 0; +} +#endif /* lucid context support */ +#endif /* HAVE_KRB5 */ + +#ifdef HAVE_KRB5 +#ifdef HAVE_LUCID_CONTEXT_SUPPORT /* Lucid context support */ +static int +prepare_krb5_rfc1964_buffer(gss_krb5_lucid_context_v1_t *lctx, + gss_buffer_desc *buf) +{ + char *p, *end; + static int constant_zero = 0; + unsigned char fakeseed[16]; + uint32_t word_send_seq; + gss_krb5_lucid_key_t enc_key; + int i; + char *skd, *dkd; + gss_buffer_desc fakeoid; + + /* + * The new Kerberos interface to get the gss context + * does not include the seed or seed_init fields + * because we never really use them. But for now, + * send down a fake buffer so we can use the same + * interface to the kernel. + */ + 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; + + if (WRITE_BYTES(&p, end, lctx->initiate)) goto out_err; + + /* seed_init and seed not used by kernel anyway */ + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; + if (write_bytes(&p, end, &fakeseed, 16)) goto out_err; + + if (WRITE_BYTES(&p, end, lctx->rfc1964_kd.sign_alg)) goto out_err; + if (WRITE_BYTES(&p, end, lctx->rfc1964_kd.seal_alg)) goto out_err; + if (WRITE_BYTES(&p, end, lctx->endtime)) goto out_err; + word_send_seq = lctx->send_seq; /* XXX send_seq is 64-bit */ + if (WRITE_BYTES(&p, end, word_send_seq)) goto out_err; + if (write_buffer(&p, end, (gss_buffer_desc*)&krb5oid)) goto out_err; + + /* derive the encryption key and copy it into buffer */ + enc_key.type = lctx->rfc1964_kd.ctx_key.type; + enc_key.length = lctx->rfc1964_kd.ctx_key.length; + if ((enc_key.data = calloc(1, enc_key.length)) == NULL) + goto out_err; + skd = (char *) lctx->rfc1964_kd.ctx_key.data; + dkd = (char *) enc_key.data; + for (i = 0; i < enc_key.length; i++) + dkd[i] = skd[i] ^ 0xf0; + if (write_lucid_keyblock(&p, end, &enc_key)) { + free(enc_key.data); + goto out_err; + } + free(enc_key.data); + + if (write_lucid_keyblock(&p, end, &lctx->rfc1964_kd.ctx_key)) + 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); + buf->length = 0; + if (enc_key.data) free(enc_key.data); + return -1; +} + +static int +prepare_krb5_rfc_cfx_buffer(gss_krb5_lucid_context_v1_t *lctx, + gss_buffer_desc *buf) +{ + printerr(0, "ERROR: prepare_krb5_rfc_cfx_buffer: not implemented\n"); + return -1; +} + +static int +serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) +{ + OM_uint32 maj_stat, min_stat; + void *return_ctx = 0; + OM_uint32 vers; + gss_krb5_lucid_context_v1_t *lctx = 0; + int retcode = 0; + + printerr(2, "DEBUG: serialize_krb5_ctx: lucid version!\n"); + maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, &ctx, + 1, &return_ctx); + if (maj_stat != GSS_S_COMPLETE) + goto out_err; + + /* Check the version returned, we only support v1 right now */ + vers = ((gss_krb5_lucid_context_version_t *)return_ctx)->version; + switch (vers) { + case 1: + lctx = (gss_krb5_lucid_context_v1_t *) return_ctx; + break; + default: + printerr(0, "ERROR: unsupported lucid sec context version %d\n", + vers); + goto out_err; + break; + } + + /* Now lctx points to a lucid context that we can send down to kernel */ + if (lctx->protocol == 0) + retcode = prepare_krb5_rfc1964_buffer(lctx, buf); + else + retcode = prepare_krb5_rfc_cfx_buffer(lctx, buf); + + maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, + (void *)lctx); + if (maj_stat != GSS_S_COMPLETE) + printerr(0, "WARN: failed to free lucid sec context\n"); + if (retcode) + goto out_err; + + return 0; + +out_err: + printerr(0, "ERROR: failed serializing krb5 context for kernel\n"); + return -1; +} + + +#else /* lucid context support */ + +static int +serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) +{ + krb5_gss_ctx_id_t kctx = (krb5_gss_ctx_id_t)ctx; + char *p, *end; + static int constant_one = 1; + static int constant_zero = 0; + uint32_t word_seq_send; + + 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_buffer(&p, end, kctx->mech_used)) goto out_err; + if (write_keyblock(&p, end, kctx->enc)) goto out_err; + if (write_keyblock(&p, end, kctx->seq)) 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); + buf->length = 0; + return -1; +} +#endif /* lucid context support */ +#endif /* HAVE_KRB5 */ + + +/* ANDROS: need to determine which fields of the spkm3_gss_ctx_id_desc_t + * are needed in the kernel for get_mic, validate, wrap, unwrap, and destroy + * and only export those fields to the kernel. + */ +static int +serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) +{ + spkm3_gss_ctx_id_desc *sctx = (spkm3_gss_ctx_id_desc *)ctx; + char *p, *end; + + printerr(1, "serialize_spkm3_ctx called\n"); + + if (!(buf->value = calloc(1, MAX_CTX_LEN))) + goto out_err; + p = buf->value; + end = buf->value + MAX_CTX_LEN; +/* buf->length +ctx_id 4 + 12 +qop 4 +mech_used 4 + 7 +ret_fl 4 +req_fl 4 +share 4 + 16 +conf_alg 4 +d_conf_key 4 + 0 +intg_alg 4 +d_intg_key 4 + 0 +kyestb 4 +owl alg 4 +*/ + if (write_buffer(&p, end, (gss_buffer_desc *)&sctx->ctx_id)) + goto out_err; + if (WRITE_BYTES(&p, end, sctx->qop)) goto out_err; + if (write_buffer(&p, end, (gss_buffer_desc *)sctx->mech_used)) goto out_err; + if (WRITE_BYTES(&p, end, sctx->ret_flags)) goto out_err; + if (WRITE_BYTES(&p, end, sctx->req_flags)) goto out_err; + if (write_buffer(&p, end, &sctx->share_key)) + goto out_err; + + if (WRITE_BYTES(&p, end, sctx->conf_alg)) goto out_err; + if (write_buffer(&p, end, &sctx->derived_conf_key)) + goto out_err; + + if (WRITE_BYTES(&p, end, sctx->intg_alg)) goto out_err; + if (write_buffer(&p, end, &sctx->derived_integ_key)) + goto out_err; + + if (WRITE_BYTES(&p, end, sctx->keyestb_alg)) goto out_err; + if (WRITE_BYTES(&p, end, sctx->owf_alg)) goto out_err; + + buf->length = p - (char *)buf->value; + return 0; +out_err: + if (buf->value) free(buf->value); + buf->length = 0; + return -1; +} + +int +serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf) +{ + gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx; + + if (g_OID_equal(&krb5oid, uctx->mech_type)) + return serialize_krb5_ctx(uctx->internal_ctx_id, buf); + else if (g_OID_equal(&spkm3oid, uctx->mech_type)) + return serialize_spkm3_ctx(uctx->internal_ctx_id, buf); + else { + printerr(0, "ERROR: attempting to serialize context with " + "unknown mechanism oid\n"); + return -1; + } +} diff -puN /dev/null utils/gssd/context.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/context.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,38 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _CONTEXT_H_ +#define _CONTEXT_H_ + +#include + +int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf); + +#endif /* _CONTEXT_H_ */ diff -puN /dev/null utils/gssd/context_heimdal.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/context_heimdal.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,256 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" + +#ifdef HAVE_HEIMDAL + +#include +#include +#include +#include +#include +#include +#include +#include +#include "err_util.h" +#include "gss_oids.h" +#include "write_bytes.h" + +#define MAX_CTX_LEN 4096 + +int write_heimdal_keyblock(char **p, char *end, krb5_keyblock *key) +{ + gss_buffer_desc tmp; + int code = -1; + + if (WRITE_BYTES(p, end, key->keytype)) goto out_err; + tmp.length = key->keyvalue.length; + tmp.value = key->keyvalue.data; + if (write_buffer(p, end, &tmp)) goto out_err; + code = 0; + out_err: + return(code); +} + +int write_heimdal_enc_key(char **p, char *end, gss_ctx_id_t ctx) +{ + krb5_keyblock enc_key, *key; + krb5_context context; + krb5_error_code ret; + int i; + char *skd, *dkd; + int code = -1; + + if ((ret = krb5_init_context(&context))) { + printerr(0, "ERROR: initializing krb5_context: %s\n", + error_message(ret)); + goto out_err; + } + + if ((ret = krb5_auth_con_getlocalsubkey(context, + ctx->auth_context, &key))){ + printerr(0, "ERROR: getting auth_context key: %s\n", + error_message(ret)); + goto out_err_free_context; + } + + memset(&enc_key, 0, sizeof(enc_key)); + printerr(1, "WARN: write_heimdal_enc_key: " + "overriding heimdal keytype\n"); + enc_key.keytype = 4 /* XXX XXX XXX XXX key->keytype */; + enc_key.keyvalue.length = key->keyvalue.length; + if ((enc_key.keyvalue.data = + calloc(1, enc_key.keyvalue.length)) == NULL) { + + printerr(0, "ERROR: allocating memory for enc key: %s\n", + error_message(ENOMEM)); + goto out_err_free_key; + } + skd = (char *) key->keyvalue.data; + dkd = (char *) enc_key.keyvalue.data; + for (i = 0; i < enc_key.keyvalue.length; i++) + dkd[i] = skd[i] ^ 0xf0; + if (write_heimdal_keyblock(p, end, &enc_key)) { + goto out_err_free_enckey; + } + + code = 0; + + out_err_free_enckey: + krb5_free_keyblock_contents(context, &enc_key); + out_err_free_key: + krb5_free_keyblock(context, key); + out_err_free_context: + krb5_free_context(context); + out_err: + printerr(2, "write_heimdal_enc_key: %s\n", code ? "FAILED" : "SUCCESS"); + return(code); +} + +int write_heimdal_seq_key(char **p, char *end, gss_ctx_id_t ctx) +{ + krb5_keyblock *key; + krb5_context context; + krb5_error_code ret; + int code = -1; + + if ((ret = krb5_init_context(&context))) { + printerr(0, "ERROR: initializing krb5_context: %s\n", + error_message(ret)); + goto out_err; + } + + if ((ret = krb5_auth_con_getlocalsubkey(context, + ctx->auth_context, &key))){ + printerr(0, "ERROR: getting auth_context key: %s\n", + error_message(ret)); + goto out_err_free_context; + } + + printerr(1, "WARN: write_heimdal_seq_key: " + "overriding heimdal keytype\n"); + key->keytype = 4; /* XXX XXX XXX XXX XXX */ + + if (write_heimdal_keyblock(p, end, key)) { + goto out_err_free_key; + } + + code = 0; + + out_err_free_key: + krb5_free_keyblock(context, key); + out_err_free_context: + krb5_free_context(context); + out_err: + printerr(2, "write_heimdal_seq_key: %s\n", code ? "FAILED" : "SUCCESS"); + return(code); +} + +/* + * The following is the kernel structure that we are filling in: + * + * struct krb5_ctx { + * int initiate; + * int seed_init; + * unsigned char seed[16]; + * int signalg; + * int sealalg; + * struct crypto_tfm *enc; + * struct crypto_tfm *seq; + * s32 endtime; + * u32 seq_send; + * struct xdr_netobj mech_used; + * }; + * + * However, note that we do not send the data fields in the + * order they appear in the structure. The order they are + * sent down in is: + * + * initiate + * seed_init + * seed + * signalg + * sealalg + * endtime + * seq_send + * mech_used + * enc key + * seq key + * + */ + +int +serialize_krb5_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf) +{ + + char *p, *end; + static int constant_one = 1; + static int constant_zero = 0; + unsigned char fakeseed[16]; + uint32_t algorithm; + + if (!(buf->value = calloc(1, MAX_CTX_LEN))) + goto out_err; + p = buf->value; + end = buf->value + MAX_CTX_LEN; + + + /* initiate: 1 => initiating 0 => accepting */ + if (ctx->more_flags & LOCAL) { + if (WRITE_BYTES(&p, end, constant_one)) goto out_err; + } + else { + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; + } + + /* seed_init: not used by kernel code */ + if (WRITE_BYTES(&p, end, constant_zero)) goto out_err; + + /* seed: not used by kernel code */ + memset(&fakeseed, 0, sizeof(fakeseed)); + if (write_bytes(&p, end, &fakeseed, 16)) goto out_err; + + /* signalg */ + algorithm = 0; /* SGN_ALG_DES_MAC_MD5 XXX */ + if (WRITE_BYTES(&p, end, algorithm)) goto out_err; + + /* sealalg */ + algorithm = 0; /* SEAL_ALG_DES XXX */ + if (WRITE_BYTES(&p, end, algorithm)) goto out_err; + + /* endtime */ + if (WRITE_BYTES(&p, end, ctx->lifetime)) goto out_err; + + /* seq_send */ + if (WRITE_BYTES(&p, end, ctx->auth_context->local_seqnumber)) + goto out_err; + /* mech_used */ + if (write_buffer(&p, end, (gss_buffer_desc*)&krb5oid)) goto out_err; + + /* enc: derive the encryption key and copy it into buffer */ + if (write_heimdal_enc_key(&p, end, ctx)) goto out_err; + + /* seq: get the sequence number key and copy it into buffer */ + if (write_heimdal_seq_key(&p, end, ctx)) goto out_err; + + buf->length = p - (char *)buf->value; + printerr(2, "serialize_krb5_ctx: returning buffer " + "with %d bytes\n", buf->length); + + return 0; +out_err: + printerr(0, "ERROR: failed exporting Heimdal krb5 ctx to kernel\n"); + if (buf->value) free(buf->value); + buf->length = 0; + return -1; +} + +#endif /* HAVE_HEIMDAL */ diff -puN /dev/null utils/gssd/err_util.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/err_util.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,92 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include "err_util.h" + +static int verbosity = 0; +static int fg = 0; + +static char message_buf[500]; +static char tmp_buf[500]; + +void initerr(char *progname, int set_verbosity, int set_fg) +{ + verbosity = set_verbosity; + fg = set_fg; + if (!fg) + openlog(progname, LOG_PID, LOG_DAEMON); +} + +void printerr(int priority, char *format, ...) +{ + va_list args; + int ret; + + /* aggregate lines: only print buffer when we get to the end of a + * line or run out of space: */ + va_start(args, format); + ret = vsnprintf(tmp_buf, sizeof(tmp_buf), format, args); + va_end(args); + if ((ret < 0) || (ret >= sizeof(tmp_buf))) + goto output; + if (strlen(tmp_buf) + strlen(message_buf) + 1 > sizeof(message_buf)) + goto output; + strcat(message_buf, tmp_buf); + if (tmp_buf[strlen(tmp_buf) - 1] == '\n') + goto output; + return; +output: + priority -= verbosity; + if (priority < 0) + priority = 0; + if (fg) { + if (priority == 0) + fprintf(stderr, "%s", message_buf); + } else { + int sys_pri; + switch (priority) { + case 0: + sys_pri = LOG_ERR; + break; + case 1: + sys_pri = LOG_DEBUG; + break; + default: + goto out; + } + syslog(sys_pri, "%s", message_buf); + } +out: + memset(message_buf, 0, sizeof(message_buf)); +} diff -puN /dev/null utils/gssd/err_util.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/err_util.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,37 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _ERR_UTIL_H_ +#define _ERR_UTIL_H_ + +void initerr(char *progname, int verbosity, int fg); +void printerr(int priority, char *format, ...); + +#endif /* _ERR_UTIL_H_ */ diff -puN /dev/null utils/gssdestroycreds/Makefile --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssdestroycreds/Makefile 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,14 @@ +# +# gss context destruction tool +# + +PROGRAM = gss_clnt_send_err +OBJS = gss_clnt_send_err.o + +include $(TOP)rules.mk + +gss_clnt_send_err.o: ../gssd/gss_clnt_send_err.c + $(CC) -c $(CFLAGS) $(?:.o=.c) + +install:: + $(INSTALLBIN) ../gssd/gss_destroy_creds $(SBINDIR)/$(PREFIX)$kgss_destroy_creds diff -puN /dev/null utils/gssd/gss_clnt_send_err.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gss_clnt_send_err.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,104 @@ +/* + Copyright (c) 2000 The Regents of the University of Michigan. + All rights reserved. + + Copyright (c) 2004 Bruce Fields + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "gssd.h" +#include "write_bytes.h" + +char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR; + +static void +usage(char *progname) +{ + fprintf(stderr, "usage: %s clntdir user [user ...]\n", progname); + exit(1); +} + +static int +do_error_downcall(int k5_fd, uid_t uid, int err) +{ + char buf[1024]; + char *p = buf, *end = buf + 1024; + unsigned int timeout = 0; + int zero = 0; + + if (WRITE_BYTES(&p, end, uid)) return -1; + if (WRITE_BYTES(&p, end, timeout)) return -1; + /* use seq_win = 0 to indicate an error: */ + if (WRITE_BYTES(&p, end, zero)) return -1; + if (WRITE_BYTES(&p, end, err)) return -1; + + if (write(k5_fd, buf, p - buf) < p - buf) return -1; + return 0; +} + +int +main(int argc, char *argv[]) +{ + int fd; + int i; + uid_t uid; + char *endptr; + struct passwd *pw; + + if (argc < 3) + usage(argv[0]); + fd = open(argv[1], O_WRONLY); + if (fd == -1) + err(1, "unable to open %s", argv[1]); + + for (i = 2; i < argc; i++) { + uid = strtol(argv[i], &endptr, 10); + if (*endptr != '\0') { + pw = getpwnam(argv[i]); + if (!pw) + err(1, "unknown user %s", argv[i]); + uid = pw->pw_uid; + } + if (do_error_downcall(fd, uid, -1)) + err(1, "failed to destroy cred for user %s", argv[i]); + } + exit(0); +} diff -puN /dev/null utils/gssd/gssd.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gssd.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,134 @@ +/* + gssd.c + + Copyright (c) 2000 The Regents of the University of Michigan. + All rights reserved. + + Copyright (c) 2000 Dug Song . + Copyright (c) 2002 Andy Adamson . + Copyright (c) 2002 Marius Aamodt Eriksen . + All rights reserved, all wrongs reversed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "gssd.h" +#include "err_util.h" +#include "gss_util.h" +#include "krb5_util.h" + +char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR; +char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE; + +void +sig_die(int signal) +{ + /* destroy krb5 machine creds */ + gssd_destroy_krb5_machine_creds(); + printerr(1, "exiting on signal %d\n", signal); + exit(1); +} + +static void +usage(char *progname) +{ + fprintf(stderr, "usage: %s [-f] [-v] [-p pipefsdir] [-k keytab]\n", + progname); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int fg = 0; + int verbosity = 0; + int opt; + extern char *optarg; + char *progname; + + while ((opt = getopt(argc, argv, "fvmp:k:")) != -1) { + switch (opt) { + case 'f': + fg = 1; + break; + case 'm': + /* Accept but ignore this. Now the default. */ + break; + case 'v': + verbosity++; + break; + case 'p': + strncpy(pipefsdir, optarg, sizeof(pipefsdir)); + if (pipefsdir[sizeof(pipefsdir)-1] != '\0') + errx(1, "pipefs path name too long"); + break; + case 'k': + strncpy(keytabfile, optarg, sizeof(keytabfile)); + if (keytabfile[sizeof(keytabfile)-1] != '\0') + errx(1, "keytab path name too long"); + break; + default: + usage(argv[0]); + break; + } + } + strncat(pipefsdir + strlen(pipefsdir), "/" GSSD_SERVICE_NAME, + sizeof(pipefsdir)-strlen(pipefsdir)); + if (pipefsdir[sizeof(pipefsdir)-1] != '\0') + errx(1, "pipefs path name too long"); + + if ((progname = strrchr(argv[0], '/'))) + progname++; + else + progname = argv[0]; + + initerr(progname, verbosity, fg); + + if (!fg && daemon(0, 0) < 0) + errx(1, "fork"); + + signal(SIGINT, sig_die); + signal(SIGTERM, sig_die); + signal(SIGHUP, sig_die); + + /* Process keytab file and get machine credentials */ + gssd_refresh_krb5_machine_creds(); + + gssd_run(); + printerr(0, "gssd_run returned!\n"); + abort(); +} diff -puN /dev/null utils/gssd/gss_destroy_creds --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gss_destroy_creds 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,11 @@ +#!/bin/bash + +path=`mount|grep rpc_pipefs|head -1|awk '{ print $3 }'` + +if [ -z "$path" ]; then + echo "unable to find rpc_pipefs; is it mounted?" + exit 1 +fi; + +find "$path" -name 'krb5' -exec gss_clnt_send_err '{}' $* ';' + diff -puN /dev/null utils/gssd/gssd.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gssd.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,89 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _RPC_GSSD_H_ +#define _RPC_GSSD_H_ + +#include +#include +#include + +#define MAX_FILE_NAMELEN 32 +#define FD_ALLOC_BLOCK 32 +#ifndef GSSD_PIPEFS_DIR +#define GSSD_PIPEFS_DIR "/var/lib/nfs/rpc_pipefs" +#endif +#define INFO "info" +#define KRB5 "krb5" +#define DNOTIFY_SIGNAL (SIGRTMIN + 3) + +#define GSSD_DEFAULT_CRED_DIR "/tmp" +#define GSSD_DEFAULT_CRED_PREFIX "krb5cc_" +#define GSSD_DEFAULT_MACHINE_CRED_SUFFIX "machine" +#define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab" +#define GSSD_SERVICE_NAME "nfs" +#define GSSD_SERVICE_NAME_LEN 3 + +/* + * The gss mechanisms that we can handle + */ +enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUTHTYPE_LIPKEY}; + + + +extern char pipefsdir[PATH_MAX]; +extern char keytabfile[PATH_MAX]; + +TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list; + +struct clnt_info { + TAILQ_ENTRY(clnt_info) list; + char *dirname; + int dir_fd; + char *servicename; + char *servername; + int prog; + int vers; + char *protocol; + int krb5_fd; + int krb5_poll_index; + int spkm3_fd; + int spkm3_poll_index; +}; + +void init_client_list(void); +int update_client_list(void); +void handle_krb5_upcall(struct clnt_info *clp); +void handle_spkm3_upcall(struct clnt_info *clp); +int gssd_acquire_cred(char *server_name); +void gssd_run(void); + + +#endif /* _RPC_GSSD_H_ */ diff -puN /dev/null utils/gssd/gssd_main_loop.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gssd_main_loop.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,144 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gssd.h" +#include "err_util.h" + +extern struct pollfd *pollarray; +extern int pollsize; + +#define POLL_MILLISECS 500 + +static volatile int dir_changed = 1; + +static void dir_notify_handler(int sig, siginfo_t *si, void *data) +{ + dir_changed = 1; +} + +static void +scan_poll_results(int ret) +{ + int i; + struct clnt_info *clp; + + for (clp = clnt_list.tqh_first; clp != NULL; clp = clp->list.tqe_next) + { + i = clp->krb5_poll_index; + if (i >= 0 && pollarray[i].revents) { + if (pollarray[i].revents & POLLHUP) + dir_changed = 1; + if (pollarray[i].revents & POLLIN) + handle_krb5_upcall(clp); + pollarray[clp->krb5_poll_index].revents = 0; + ret--; + if (!ret) + break; + } + i = clp->spkm3_poll_index; + if (i >= 0 && pollarray[i].revents) { + if (pollarray[i].revents & POLLHUP) + dir_changed = 1; + if (pollarray[i].revents & POLLIN) + handle_spkm3_upcall(clp); + pollarray[clp->spkm3_poll_index].revents = 0; + ret--; + if (!ret) + break; + } + } +}; + +void +gssd_run() +{ + int ret; + struct sigaction dn_act; + int fd; + + /* Taken from linux/Documentation/dnotify.txt: */ + dn_act.sa_sigaction = dir_notify_handler; + sigemptyset(&dn_act.sa_mask); + dn_act.sa_flags = SA_SIGINFO; + sigaction(DNOTIFY_SIGNAL, &dn_act, NULL); + + if ((fd = open(pipefsdir, O_RDONLY)) == -1) { + printerr(0, "ERROR: failed to open %s: %s\n", + pipefsdir, strerror(errno)); + exit(1); + } + fcntl(fd, F_SETSIG, DNOTIFY_SIGNAL); + fcntl(fd, F_NOTIFY, DN_CREATE|DN_DELETE|DN_MODIFY|DN_MULTISHOT); + + init_client_list(); + + while (1) { + while (dir_changed) { + dir_changed = 0; + if (update_client_list()) { + printerr(0, "ERROR: couldn't update " + "client list\n"); + exit(1); + } + } + /* race condition here: dir_changed could be set before we + * enter the poll, and we'd never notice if it weren't for the + * timeout. */ + ret = poll(pollarray, pollsize, POLL_MILLISECS); + if (ret < 0) { + if (errno != EINTR) + printerr(0, + "WARNING: error return from poll\n"); + } else if (ret == 0) { + /* timeout */ + } else { /* ret > 0 */ + scan_poll_results(ret); + } + } + close(fd); + return; +} diff -puN /dev/null utils/gssd/gssd.man --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gssd.man 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,63 @@ +.\" +.\" rpc.gssd(8) +.\" +.\" Copyright (C) 2003 J. Bruce Fields +.TH rpc.gssd 8 "17 Mar 2003" +.SH NAME +rpc.gssd \- rpcsec_gss daemon +.SH SYNOPSIS +.B "rpc.gssd [-f] [-k keytab] [-p pipefsdir] [-v]" +.SH DESCRIPTION +The rpcsec_gss protocol gives a means of using the gss-api generic security +api to provide security for protocols using rpc (in particular, nfs). Before +exchanging any rpc requests using rpcsec_gss, the rpc client must first +establish a security context. The linux kernel's implementation of rpcsec_gss +depends on the userspace daemon +.B rpc.gssd +to establish security contexts. The +.B rpc.gssd +daemon uses files in the rpc_pipefs filesystem to communicate with the kernel. + +.SH OPTIONS +.TP +.B -f +Runs +.B rpc.gssd +in the foreground and sends output to stderr (as opposed to syslogd) +.TP +.B -k keytab +Tells +.B rpc.gssd +to use the keys for principals nfs/hostname in +.I keytab +to obtain machine credentials. +The default value is "/etc/krb5.keytab". +.\".TP +.\".B -m +.\"Ordinarily, +.\".B rpc.gssd +.\"looks for a cached ticket for user $UID in /tmp/krb5cc_$UID. +.\"With the -m option, the user with uid 0 will be treated specially, and will +.\"be mapped instead to the credentials for the principal nfs/hostname found in +.\"the keytab file. +.\"(This option is now the default and is ignored if specified.) +.TP +.B -p path +Tells +.B rpc.gssd +where to look for the rpc_pipefs filesystem. The default value is +"/var/lib/nfs/rpc_pipefs". +.TP +.B -v +Increases the verbosity of the output (can be specified multiple times). +.SH SEE ALSO +.BR rpc.svcgssd(8) +.SH AUTHORS +.br +Dug Song +.br +Andy Adamson +.br +Marius Aamodt Eriksen +.br +J. Bruce Fields diff -puN /dev/null utils/gssd/gssd_proc.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gssd_proc.c 2004-10-27 18:02:50.000000000 -0400 @@ -0,0 +1,670 @@ +/* + gssd_proc.c + + Copyright (c) 2000-2004 The Regents of the University of Michigan. + All rights reserved. + + Copyright (c) 2000 Dug Song . + Copyright (c) 2001 Andy Adamson . + Copyright (c) 2002 Marius Aamodt Eriksen . + Copyright (c) 2002 Bruce Fields + Copyright (c) 2004 Kevin Coffman + All rights reserved, all wrongs reversed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "config.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gssd.h" +#include "err_util.h" +#include "gss_util.h" +#include "gss_oids.h" +#include "krb5_util.h" +#include "context.h" + +/* + * pollarray: + * array of struct pollfd suitable to pass to poll. initialized to + * zero - a zero struct is ignored by poll() because the events mask is 0. + * + * clnt_list: + * linked list of struct clnt_info which associates a clntXXX directory + * with an index into pollarray[], and other basic data about that client. + * + * Directory structure: created by the kernel nfs client + * /pipefsdir/clntXX : one per rpc_clnt struct in the kernel + * /pipefsdir/clntXX/krb5 : read uid for which kernel wants + * a context, write the resulting context + * /pipefsdir/clntXX/info : stores info such as server name + * + * Algorithm: + * Poll all /pipefsdir/clntXX/krb5 files. When ready, data read + * is a uid; performs rpcsec_gss context initialization protocol to + * get a cred for that user. Writes result to corresponding krb5 file + * in a form the kernel code will understand. + * In addition, we make sure we are notified whenever anything is + * created or destroyed in pipefsdir/ or in an of the clntXX directories, + * and rescan the whole pipefsdir when this happens. + */ + +struct pollfd * pollarray; + +int pollsize; /* the size of pollaray (in pollfd's) */ + +/* XXX buffer problems: */ +static int +read_service_info(char *info_file_name, char **servicename, char **servername, + int *prog, int *vers, char **protocol) { +#define INFOBUFLEN 256 + char buf[INFOBUFLEN]; + static char dummy[128]; + int nbytes; + static char service[128]; + static char address[128]; + char program[16]; + char version[16]; + char protoname[16]; + in_addr_t inaddr; + int fd = -1; + struct hostent *ent = NULL; + int numfields; + + *servicename = *servername = *protocol = NULL; + + if ((fd = open(info_file_name, O_RDONLY)) == -1) { + printerr(0, "ERROR: can't open %s: %s\n", info_file_name, + strerror(errno)); + goto fail; + } + if ((nbytes = read(fd, buf, INFOBUFLEN)) == -1) + goto fail; + close(fd); + + numfields = sscanf(buf,"RPC server: %s\n" + "service: %s %s version %s\n" + "address: %s\n" + "protocol: %s\n", + dummy, + service, program, version, + address, + protoname); + + if (numfields == 5) { + strcpy(protoname, "tcp"); + } else if (numfields != 6) { + goto fail; + } + + /* check service, program, and version */ + if(memcmp(service, "nfs", 3)) return -1; + *prog = atoi(program + 1); /* skip open paren */ + *vers = atoi(version); + if((*prog != 100003) || ((*vers != 2) && (*vers != 3) && (*vers != 4))) + goto fail; + + /* create service name */ + inaddr = inet_addr(address); + if (!(ent = gethostbyaddr(&inaddr, sizeof(inaddr), AF_INET))) { + printerr(0, "ERROR: can't resolve server %s name\n", address); + goto fail; + } + if (!(*servername = calloc(strlen(ent->h_name) + 1, 1))) + goto fail; + memcpy(*servername, ent->h_name, strlen(ent->h_name)); + snprintf(buf, INFOBUFLEN, "%s@%s", service, ent->h_name); + if (!(*servicename = calloc(strlen(buf) + 1, 1))) + goto fail; + memcpy(*servicename, buf, strlen(buf)); + + if (!(*protocol = strdup(protoname))) + goto fail; + return 0; +fail: + printerr(0, "ERROR: failed to read service info\n"); + if (fd != -1) close(fd); + if (*servername) free(*servername); + if (*servicename) free(*servicename); + if (*protocol) free(*protocol); + return -1; +} + +static void +destroy_client(struct clnt_info *clp) +{ + if (clp->dir_fd != -1) close(clp->dir_fd); + if (clp->krb5_fd != -1) close(clp->krb5_fd); + if (clp->spkm3_fd != -1) close(clp->spkm3_fd); + if (clp->dirname) free(clp->dirname); + if (clp->servicename) free(clp->servicename); + if (clp->servername) free(clp->servername); + if (clp->protocol) free(clp->protocol); + free(clp); +} + +static struct clnt_info * +insert_new_clnt(void) +{ + struct clnt_info *clp = NULL; + + if (!(clp = (struct clnt_info *)calloc(1,sizeof(struct clnt_info)))) { + printerr(0, "ERROR: can't malloc clnt_info: %s\n", + strerror(errno)); + goto out; + } + clp->krb5_poll_index = -1; + clp->spkm3_poll_index = -1; + clp->krb5_fd = -1; + clp->spkm3_fd = -1; + clp->dir_fd = -1; + + TAILQ_INSERT_HEAD(&clnt_list, clp, list); +out: + return clp; +} + +static int +process_clnt_dir_files(struct clnt_info * clp) +{ + char kname[32]; + char sname[32]; + char info_file_name[32]; + + snprintf(kname, sizeof(kname), "%s/krb5", clp->dirname); + clp->krb5_fd = open(kname, O_RDWR); + snprintf(sname, sizeof(sname), "%s/spkm3", clp->dirname); + clp->spkm3_fd = open(sname, O_RDWR); + if((clp->krb5_fd == -1) && (clp->spkm3_fd == -1)) + return -1; + snprintf(info_file_name, sizeof(info_file_name), "%s/info", + clp->dirname); + if (read_service_info(info_file_name, &clp->servicename, + &clp->servername, &clp->prog, &clp->vers, + &clp->protocol)) + return -1; + return 0; +} + +static int +get_poll_index(int *ind) +{ + int i; + + *ind = -1; + for (i=0; idirname = calloc(strlen(dir) + 1, 1))) { + goto fail_destroy_client; + } + memcpy(clp->dirname, dir, strlen(dir)); + if ((clp->dir_fd = open(clp->dirname, O_RDONLY)) == -1) { + printerr(0, "ERROR: can't open %s: %s\n", + clp->dirname, strerror(errno)); + goto fail_destroy_client; + } + fcntl(clp->dir_fd, F_SETSIG, DNOTIFY_SIGNAL); + fcntl(clp->dir_fd, F_NOTIFY, DN_CREATE | DN_DELETE | DN_MULTISHOT); + + if (process_clnt_dir_files(clp)) + goto fail_keep_client; + + if(clp->krb5_fd != -1) { + if (get_poll_index(&clp->krb5_poll_index)) { + printerr(0, "ERROR: Too many krb5 clients\n"); + goto fail_destroy_client; + } + pollarray[clp->krb5_poll_index].fd = clp->krb5_fd; + pollarray[clp->krb5_poll_index].events |= POLLIN; + } + + if(clp->spkm3_fd != -1) { + if (get_poll_index(&clp->spkm3_poll_index)) { + printerr(0, "ERROR: Too many spkm3 clients\n"); + goto fail_destroy_client; + } + pollarray[clp->spkm3_poll_index].fd = clp->spkm3_fd; + pollarray[clp->spkm3_poll_index].events |= POLLIN; + } + + return; + +fail_destroy_client: + if (clp) { + TAILQ_REMOVE(&clnt_list, clp, list); + destroy_client(clp); + } +fail_keep_client: + /* We couldn't find some subdirectories, but we keep the client + * around in case we get a notification on the directory when the + * subdirectories are created. */ + return; +} + +void +init_client_list(void) +{ + TAILQ_INIT(&clnt_list); + /* Eventually plan to grow/shrink poll array: */ + pollsize = FD_ALLOC_BLOCK; + pollarray = calloc(pollsize, sizeof(struct pollfd)); +} + +static void +destroy_client_list(void) +{ + struct clnt_info *clp; + + printerr(1, "processing client list\n"); + + while (clnt_list.tqh_first != NULL) { + clp = clnt_list.tqh_first; + TAILQ_REMOVE(&clnt_list, clp, list); + destroy_client(clp); + } +} + +/* Used to read (and re-read) list of clients, set up poll array. */ +int +update_client_list(void) +{ + struct dirent **namelist; + int i,j; + + destroy_client_list(); + + if (chdir(pipefsdir) < 0) { + printerr(0, "ERROR: can't chdir to %s: %s\n", + pipefsdir, strerror(errno)); + return -1; + } + + memset(pollarray, 0, pollsize * sizeof(struct pollfd)); + + j = scandir(pipefsdir, &namelist, NULL, alphasort); + if (j < 0) { + printerr(0, "ERROR: can't scandir %s: %s\n", + pipefsdir, strerror(errno)); + return -1; + } + for (i=0; i < j; i++) { + if (i < FD_ALLOC_BLOCK + && !strncmp(namelist[i]->d_name, "clnt", 4)) + process_clnt_dir(namelist[i]->d_name); + free(namelist[i]); + } + + free(namelist); + return 0; +} + +static int +do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd, + gss_buffer_desc *context_token) +{ + char buf[2048]; + char *p = buf, *end = buf + 2048; + unsigned int timeout = 0; /* XXX decide on a reasonable value */ + + printerr(1, "doing downcall\n"); + + if (WRITE_BYTES(&p, end, uid)) goto out_err; + /* Not setting any timeout for now: */ + if (WRITE_BYTES(&p, end, timeout)) goto out_err; + if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err; + if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err; + if (write_buffer(&p, end, context_token)) goto out_err; + + if (write(k5_fd, buf, p - buf) < p - buf) goto out_err; + return 0; +out_err: + printerr(0, "Failed to write downcall!\n"); + return -1; +} + +static int +do_error_downcall(int k5_fd, uid_t uid, int err) +{ + char buf[1024]; + char *p = buf, *end = buf + 1024; + unsigned int timeout = 0; + int zero = 0; + + printerr(1, "doing error downcall\n"); + + if (WRITE_BYTES(&p, end, uid)) goto out_err; + if (WRITE_BYTES(&p, end, timeout)) goto out_err; + /* use seq_win = 0 to indicate an error: */ + if (WRITE_BYTES(&p, end, zero)) goto out_err; + if (WRITE_BYTES(&p, end, err)) goto out_err; + + if (write(k5_fd, buf, p - buf) < p - buf) goto out_err; + return 0; +out_err: + printerr(0, "Failed to write error downcall!\n"); + return -1; +} + +/* + * Create an RPC connection and establish an authenticated + * gss context with a server. + */ +int create_auth_rpc_client(struct clnt_info *clp, + AUTH **auth_return, + uid_t uid, + int authtype) +{ + CLIENT *rpc_clnt = NULL; + struct rpc_gss_sec sec; + AUTH *auth = NULL; + uid_t save_uid = -1; + int retval = -1; + OM_uint32 min_stat; + + sec.qop = GSS_C_QOP_DEFAULT; + sec.svc = RPCSEC_GSS_SVC_NONE; + sec.cred = GSS_C_NO_CREDENTIAL; + sec.req_flags = 0; + if (authtype == AUTHTYPE_KRB5) { + sec.mech = (gss_OID)&krb5oid; + sec.req_flags = GSS_C_MUTUAL_FLAG; + } + else if (authtype == AUTHTYPE_SPKM3) { + sec.mech = (gss_OID)&spkm3oid; + sec.req_flags = GSS_C_ANON_FLAG; + } + else { + printerr(0, "ERROR: Invalid authentication type (%d) " + "in create_auth_rpc_client\n", authtype); + goto out_fail; + } + + + if (authtype == AUTHTYPE_KRB5) { +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES + /* + * Do this before creating rpc connection since we won't need + * rpc connection if it fails! + */ + if (limit_krb5_enctypes(&sec, uid)) { + printerr(1, "WARNING: Failed while limiting krb5 " + "encryption types for user with uid %d\n", + uid); + goto out_fail; + } +#endif + } + + /* Create the context as the user (not as root) */ + save_uid = geteuid(); + if (seteuid(uid) != 0) { + printerr(0, "WARNING: Failed to seteuid for " + "user with uid %d\n", uid); + goto out_fail; + } + printerr(2, "creating context using euid %d (save_uid %d)\n", + geteuid(), save_uid); + + /* create an rpc connection to the nfs server */ + + printerr(2, "creating %s client for server %s\n", clp->protocol, + clp->servername); + if ((rpc_clnt = clnt_create(clp->servername, clp->prog, clp->vers, + clp->protocol)) == NULL) { + printerr(0, "WARNING: can't create rpc_clnt for server " + "%s for user with uid %d\n", + clp->servername, uid); + goto out_fail; + } + + printerr(2, "creating context with server %s\n", clp->servicename); + auth = authgss_create_default(rpc_clnt, clp->servicename, &sec); + if (!auth) { + /* Our caller should print appropriate message */ + printerr(2, "WARNING: Failed to create krb5 context for " + "user with uid %d for server %s\n", + uid, clp->servername); + goto out_fail; + } + + /* Restore euid to original value */ + if (seteuid(save_uid) != 0) { + printerr(0, "WARNING: Failed to restore euid" + " to uid %d\n", save_uid); + goto out_fail; + } + save_uid = -1; + + /* Success !!! */ + *auth_return = auth; + retval = 0; + + out_fail: + if ((save_uid != -1) && (seteuid(save_uid) != 0)) { + printerr(0, "WARNING: Failed to restore euid" + " to uid %d (in error path)\n", save_uid); + } + if (sec.cred != GSS_C_NO_CREDENTIAL) + gss_release_cred(&min_stat, &sec.cred); + if (rpc_clnt) clnt_destroy(rpc_clnt); + + return retval; +} + + +/* + * this code uses the userland rpcsec gss library to create a krb5 + * context on behalf of the kernel + */ +void +handle_krb5_upcall(struct clnt_info *clp) +{ + uid_t uid; + AUTH *auth; + struct authgss_private_data pd; + gss_buffer_desc token; + char **credlist = NULL; + char **ccname; + + printerr(1, "handling krb5 upcall\n"); + + token.length = 0; + token.value = NULL; + + if (read(clp->krb5_fd, &uid, sizeof(uid)) < sizeof(uid)) { + printerr(0, "WARNING: failed reading uid from krb5 " + "upcall pipe: %s\n", strerror(errno)); + goto out; + } + + if (uid == 0) { + int success = 0; + + /* + * Get a list of credential cache names and try each + * of them until one works or we've tried them all + */ + if (gssd_get_krb5_machine_cred_list(&credlist)) { + printerr(0, "WARNING: Failed to obtain machine " + "credentials for connection to " + "server %s\n", clp->servername); + goto out_return_error; + } + for (ccname = credlist; ccname && *ccname; ccname++) { + gssd_setup_krb5_machine_gss_ccache(*ccname); + if ((create_auth_rpc_client(clp, &auth, uid, + AUTHTYPE_KRB5)) == 0) { + /* Success! */ + success++; + break; + } + printerr(2, "WARNING: Failed to create krb5 context " + "for user with uid %d with credentials " + "cache %s for server %s\n", + uid, *ccname, clp->servername); + } + gssd_free_krb5_machine_cred_list(credlist); + if (!success) { + printerr(0, "WARNING: Failed to create krb5 context " + "for user with uid %d with any " + "credentials cache for server %s\n", + uid, clp->servername); + goto out_return_error; + } + } + else { + /* Tell krb5 gss which credentials cache to use */ + gssd_setup_krb5_user_gss_ccache(uid, clp->servername); + + if (create_auth_rpc_client(clp, &auth, uid, AUTHTYPE_KRB5)) { + printerr(0, "WARNING: Failed to create krb5 context " + "for user with uid %d for server %s\n", + uid, clp->servername); + goto out_return_error; + } + } + + if (!authgss_get_private_data(auth, &pd)) { + printerr(0, "WARNING: Failed to obtain authentication " + "data for user with uid %d for server %s\n", + uid, clp->servername); + goto out_return_error; + } + + if (serialize_context_for_kernel(pd.pd_ctx, &token)) { + printerr(0, "WARNING: Failed to serialize krb5 context for " + "user with uid %d for server %s\n", + uid, clp->servername); + goto out_return_error; + } + + do_downcall(clp->krb5_fd, uid, &pd, &token); + + if (token.value) + free(token.value); +out: + return; + +out_return_error: + do_error_downcall(clp->krb5_fd, uid, -1); + return; +} + +/* + * this code uses the userland rpcsec gss library to create an spkm3 + * context on behalf of the kernel + */ +void +handle_spkm3_upcall(struct clnt_info *clp) +{ + uid_t uid; + AUTH *auth; + struct authgss_private_data pd; + gss_buffer_desc token; + + printerr(2, "handling spkm3 upcall\n"); + + token.length = 0; + token.value = NULL; + + if (read(clp->spkm3_fd, &uid, sizeof(uid)) < sizeof(uid)) { + printerr(0, "WARNING: failed reading uid from spkm3 " + "upcall pipe: %s\n", strerror(errno)); + goto out; + } + + if (create_auth_rpc_client(clp, &auth, uid, AUTHTYPE_SPKM3)) { + printerr(0, "WARNING: Failed to create spkm3 context for " + "user with uid %d\n", uid); + goto out_return_error; + } + + if (!authgss_get_private_data(auth, &pd)) { + printerr(0, "WARNING: Failed to obtain authentication " + "data for user with uid %d for server %s\n", + uid, clp->servername); + goto out_return_error; + } + + if (serialize_context_for_kernel(pd.pd_ctx, &token)) { + printerr(0, "WARNING: Failed to serialize spkm3 context for " + "user with uid %d for server\n", + uid, clp->servername); + goto out_return_error; + } + + do_downcall(clp->spkm3_fd, uid, &pd, &token); + + if (token.value) + free(token.value); +out: + return; + +out_return_error: + do_error_downcall(clp->spkm3_fd, uid, -1); + return; +} diff -puN /dev/null utils/gssd/gss_oids.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gss_oids.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,39 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +/* from kerberos source, gssapi_krb5.c */ +gss_OID_desc krb5oid = + {9, "\052\206\110\206\367\022\001\002\002"}; + +gss_OID_desc spkm3oid = + {7, "\052\006\001\005\005\001\003"}; diff -puN /dev/null utils/gssd/gss_oids.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gss_oids.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,46 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _GSS_OIDS_H_ +#define _GSS_OIDS_H_ + +#include +#include + +extern gss_OID_desc krb5oid; +extern gss_OID_desc spkm3oid; + +#ifndef g_OID_equal +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(unsigned int) (o1)->length) == 0)) +#endif + +#endif /* _GSS_OIDS_H_ */ diff -puN /dev/null utils/gssd/gss_util.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gss_util.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,212 @@ +/* + * Adapted in part from MIT Kerberos 5-1.2.1 slave/kprop.c and from + * http://docs.sun.com/?p=/doc/816-1331/6m7oo9sms&a=view + * + * Copyright (c) 2002 The Regents of the University of Michigan. + * All rights reserved. + * + * Andy Adamson + * J. Bruce Fields + * Marius Aamodt Eriksen + */ + +/* + * slave/kprop.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * Copyright 1994 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gss_util.h" +#include "err_util.h" +#include "gssd.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_COM_ERR_H +#include +#endif + +/* Global gssd_credentials handle */ +gss_cred_id_t gssd_creds; + +gss_OID g_mechOid = GSS_C_NULL_OID;; + +#if 0 +static void +display_status_1(char *m, u_int32_t code, int type, const gss_OID mech) +{ + u_int32_t maj_stat, min_stat; + gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; + u_int32_t msg_ctx = 0; + char *typestr; + + switch (type) { + case GSS_C_GSS_CODE: + typestr = "GSS"; + break; + case GSS_C_MECH_CODE: + typestr = "mechanism"; + break; + default: + return; + /* NOTREACHED */ + } + + for (;;) { + maj_stat = gss_display_status(&min_stat, code, + type, mech, &msg_ctx, &msg); + if (maj_stat != GSS_S_COMPLETE) { + printerr(0, "ERROR: in call to " + "gss_display_status called from %s\n", m); + break; + } else { + printerr(0, "ERROR: GSS-API: (%s) error in %s(): %s\n", + typestr, m, (char *)msg.value); + } + + if (msg.length != 0) + (void) gss_release_buffer(&min_stat, &msg); + + if (msg_ctx == 0) + break; + } +} +#endif + +static void +display_status_2(char *m, u_int32_t major, u_int32_t minor, const gss_OID mech) +{ + u_int32_t maj_stat1, min_stat1; + u_int32_t maj_stat2, min_stat2; + gss_buffer_desc maj_gss_buf = GSS_C_EMPTY_BUFFER; + gss_buffer_desc min_gss_buf = GSS_C_EMPTY_BUFFER; + char maj_buf[30], min_buf[30]; + char *maj, *min; + u_int32_t msg_ctx = 0; + + /* Get major status message */ + maj_stat1 = gss_display_status(&min_stat1, major, + GSS_C_GSS_CODE, mech, &msg_ctx, &maj_gss_buf); + + if (maj_stat1 != GSS_S_COMPLETE) { + snprintf(maj_buf, sizeof(maj_buf), "(0x%08x)", major); + maj = &maj_buf[0]; + } else { + maj = maj_gss_buf.value; + } + + /* Get minor status message */ + maj_stat2 = gss_display_status(&min_stat2, minor, + GSS_C_MECH_CODE, mech, &msg_ctx, &min_gss_buf); + + if (maj_stat2 != GSS_S_COMPLETE) { + snprintf(min_buf, sizeof(min_buf), "(0x%08x)", minor); + min = &min_buf[0]; + } else { + min = min_gss_buf.value; + } + + printerr(0, "ERROR: GSS-API: error in %s(): %s - %s\n", + m, maj, min); + + if (maj_gss_buf.length != 0) + (void) gss_release_buffer(&min_stat1, &maj_gss_buf); + if (min_gss_buf.length != 0) + (void) gss_release_buffer(&min_stat2, &min_gss_buf); +} + +void +pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, const gss_OID mech) +{ + display_status_2(msg, maj_stat, min_stat, mech); +} + +int +gssd_acquire_cred(char *server_name) +{ + gss_buffer_desc name; + gss_name_t target_name; + u_int32_t maj_stat, min_stat; + u_int32_t ignore_maj_stat, ignore_min_stat; + + name.value = (void *)server_name; + name.length = strlen(server_name); + + maj_stat = gss_import_name(&min_stat, &name, + (const gss_OID) GSS_C_NT_HOSTBASED_SERVICE, + &target_name); + + if (maj_stat != GSS_S_COMPLETE) { + pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid); + return (FALSE); + } + + maj_stat = gss_acquire_cred(&min_stat, target_name, 0, + GSS_C_NULL_OID_SET, GSS_C_ACCEPT, + &gssd_creds, NULL, NULL); + + ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name); + + if (maj_stat != GSS_S_COMPLETE) + pgsserr("gss_acquire_cred", maj_stat, min_stat, g_mechOid); + + return (maj_stat == GSS_S_COMPLETE); +} diff -puN /dev/null utils/gssd/gss_util.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/gss_util.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,44 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _GSS_UTIL_H_ +#define _GSS_UTIL_H_ + +#include +#include +#include "write_bytes.h" + +extern gss_cred_id_t gssd_creds; + +int gssd_acquire_cred(char *server_name); +void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, + const gss_OID mech); + +#endif /* _GSS_UTIL_H_ */ diff -puN /dev/null utils/gssd/krb5_util.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/krb5_util.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,809 @@ +/* + * Adapted in part from MIT Kerberos 5-1.2.1 slave/kprop.c and from + * http://docs.sun.com/?p=/doc/816-1331/6m7oo9sms&a=view + * + * Copyright (c) 2002-2004 The Regents of the University of Michigan. + * All rights reserved. + * + * Andy Adamson + * J. Bruce Fields + * Marius Aamodt Eriksen + * Kevin Coffman + */ + +/* + * slave/kprop.c + * + * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* + * Copyright 1994 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* + krb5_util.c + + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "config.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_PRIVATE_KRB5_FUNCTIONS +#include +#endif +#include +#include + +#include "gssd.h" +#include "err_util.h" +#include "gss_util.h" +#include "gss_oids.h" +#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; + +/*==========================*/ +/*=== Internal routines ===*/ +/*==========================*/ + +static int select_krb5_ccache(const struct dirent *d); +static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d); +static int gssd_get_single_krb5_cred(krb5_context context, + krb5_keytab kt, struct gssd_k5_kt_princ *ple); +static int gssd_have_realm_ple(krb5_data *realm); +static int gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, + char *kt_name); + +/* + * Called from the scandir function to weed out potential krb5 + * credentials cache files + * + * Returns: + * 0 => don't select this one + * 1 => select this one + */ +static int +select_krb5_ccache(const struct dirent *d) +{ + /* Don't consider anything but regular files. (No symlinks, etc.) */ + if (d->d_type != DT_REG) + return 0; + + if (strstr(d->d_name, GSSD_DEFAULT_CRED_PREFIX)) + return 1; + else + return 0; +} + +/* + * Look in the GSSD_DEFAULT_CRED_DIR for files that look like they + * are Kerberos Credential Cache files for a given UID. Return + * non-zero and the dirent pointer for the entry most likely to be + * what we want. Otherwise, return zero and no dirent pointer. + * The caller is responsible for freeing the dirent if one is returned. + * + * Returns: + * 0 => could not find an existing entry + * 1 => found an existing entry + */ +static int +gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d) +{ + struct dirent **namelist; + int n; + int i; + int found = 0; + struct dirent *best_match_dir = NULL; + struct stat best_match_stat, tmp_stat; + + *d = NULL; + n = scandir(GSSD_DEFAULT_CRED_DIR, &namelist, select_krb5_ccache, 0); + if (n < 0) { + perror("scandir looking for krb5 credentials caches"); + } + else if (n > 0) { + char substring[128]; + char statname[1024]; + snprintf(substring, sizeof(substring), "_%d", uid); + for (i = 0; i < n; i++) { + printerr(3, "CC file '%s' being considered\n", + namelist[i]->d_name); + if (strstr(namelist[i]->d_name, substring)) { + snprintf(statname, sizeof(statname), + "%s/%s", GSSD_DEFAULT_CRED_DIR, + namelist[i]->d_name); + if (stat(statname, &tmp_stat)) { + printerr(0, "Error doing stat " + "on file '%s'\n", + statname); + continue; + } + printerr(3, "CC file '%s' matches " + "name check and has " + "mtime of %u\n", + namelist[i]->d_name, + tmp_stat.st_mtime); + /* if more than one match is found, + * return the most recent (the one + * with the latest mtime), + * and don't free the dirent */ + if (!found) { + best_match_dir = namelist[i]; + best_match_stat = tmp_stat; + found++; + } + else { + /* + * If the current match has + * an mtime later than the + * one we are looking at, + * then use the current match. + * Otherwise, we still have + * the best match. + */ + if (tmp_stat.st_mtime > + best_match_stat.st_mtime) { + free(best_match_dir); + best_match_dir = namelist[i]; + best_match_stat = tmp_stat; + } + else { + free(namelist[i]); + } + printerr(3, "CC file '%s' is our " + "current best match " + "with mtime of %u\n", + best_match_dir->d_name, + best_match_stat.st_mtime); + } + } + else + free(namelist[i]); + } + free(namelist); + } + if (found) + { + *d = best_match_dir; + } + return found; +} + + +#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; +/* krb5_enctype enctypes[] = {ENCTYPE_DES3_CBC_SHA1}; + ENCTYPE_ARCFOUR_HMAC, */ + krb5_enctype enctypes[] = {ENCTYPE_DES3_CBC_SHA1, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC}; + int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]); + + maj_stat = gss_acquire_cred(&min_stat, NULL, 0, + GSS_C_NULL_OID_SET, GSS_C_INITIATE, + &credh, NULL, NULL); + + if (maj_stat != GSS_S_COMPLETE) { + printerr(0, "WARNING: error from gss_acquire_cred " + "for user with uid %d (%s)\n", + uid, error_message(min_stat)); + return -1; + } + + maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid, + num_enctypes, &enctypes); + if (maj_stat != GSS_S_COMPLETE) { + printerr(0, "WARNING: error from gss_set_allowable_enctypes " + "for user with uid %d (%s)\n", + uid, error_message(min_stat)); + 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. + * Checks to see if current credentials are expired, + * if not, uses the keytab to obtain new credentials. + * + * Returns: + * 0 => success (or credentials have not expired) + * nonzero => error + */ +static int +gssd_get_single_krb5_cred(krb5_context context, + krb5_keytab kt, + struct gssd_k5_kt_princ *ple) +{ + krb5_get_init_creds_opt options; + krb5_creds my_creds; + krb5_ccache ccache = NULL; + char kt_name[BUFSIZ]; + char cc_name[BUFSIZ]; + int code; + time_t now = time(0); + + memset(&my_creds, 0, sizeof(my_creds)); + + if (ple->ccname && ple->endtime > now) { + printerr(2, "INFO: Credentials in CC '%s' are good until %d\n", + ple->ccname, ple->endtime); + code = 0; + goto out; + } + + if ((code = krb5_kt_get_name(context, kt, kt_name, BUFSIZ))) { + printerr(0, "ERROR: Unable to get keytab name in " + "gssd_get_single_krb5_cred\n"); + goto out; + } + + krb5_get_init_creds_opt_init(&options); + krb5_get_init_creds_opt_set_address_list(&options, NULL); + +#ifdef TEST_SHORT_LIFETIME + /* set a short lifetime (for debugging only!) */ + printerr(0, "WARNING: Using (debug) short machine cred lifetime!\n"); + krb5_get_init_creds_opt_set_tkt_life(&options, 5*60); +#endif + if ((code = krb5_get_init_creds_keytab(context, &my_creds, ple->princ, + kt, 0, 0, &options))) { + char *pname; + if ((krb5_unparse_name(context, ple->princ, &pname))) { + pname = NULL; + } + printerr(0, "WARNING: %s while getting initial ticket for " + "principal '%s' from keytab '%s'\n", + error_message(code), + pname ? pname : "", kt_name); + if (pname) krb5_free_unparsed_name(context, pname); + goto out; + } + + /* + * Initialize cache file which we're going to be using + */ + + snprintf(cc_name, sizeof(cc_name), "FILE:%s/%s%s_%s", + GSSD_DEFAULT_CRED_DIR, GSSD_DEFAULT_CRED_PREFIX, + GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm); + ple->endtime = my_creds.times.endtime; + ple->ccname = strdup(cc_name); + if (ple->ccname == NULL) { + printerr(0, "ERROR: no storage to duplicate credentials " + "cache name\n"); + code = ENOMEM; + goto out; + } + if ((code = krb5_cc_resolve(context, cc_name, &ccache))) { + printerr(0, "ERROR: %s while opening credential cache '%s'\n", + error_message(code), cc_name); + goto out; + } + if ((code = krb5_cc_initialize(context, ccache, ple->princ))) { + printerr(0, "ERROR: %s while initializing credential " + "cache '%s'\n", error_message(code), cc_name); + goto out; + } + if ((code = krb5_cc_store_cred(context, ccache, &my_creds))) { + printerr(0, "ERROR: %s while storing credentials in '%s'\n", + error_message(code), cc_name); + goto out; + } + + code = 0; + printerr(1, "Using (machine) credentials cache: '%s'\n", cc_name); + out: + if (ccache) + krb5_cc_close(context, ccache); + krb5_free_cred_contents(context, &my_creds); + return (code); +} + +/* + * Determine if we already have a ple for the given realm + * + * Returns: + * 0 => no ple found for given realm + * 1 => found ple for given realm + */ +static int +gssd_have_realm_ple(krb5_data *realm) +{ + struct gssd_k5_kt_princ *ple; + + for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { + if ((realm->length == strlen(ple->realm)) && + (strncmp(realm->data, ple->realm, realm->length) == 0)) { + return 1; + } + } + return 0; +} + +/* + * Process the given keytab file and create a list of principals we + * might use to perform mount operations. + * + * Returns: + * 0 => Sucess + * nonzero => Error + */ +static int +gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, char *kt_name) +{ + krb5_kt_cursor cursor; + krb5_keytab_entry kte; + krb5_error_code code; + struct gssd_k5_kt_princ *ple; + int retval = -1; + + /* + * Look through each entry in the keytab file and determine + * if we might want to use it later to do a mount. If so, + * save info in the global principal list + * (gssd_k5_kt_princ_list). + * Note: (ple == principal list entry) + */ + if ((code = krb5_kt_start_seq_get(context, kt, &cursor))) { + printerr(0, "ERROR: %s while beginning keytab scan " + "for keytab '%s'\n", + error_message(code), kt_name); + retval = code; + goto out; + } + + while ((code = krb5_kt_next_entry(context, kt, &kte, &cursor)) == 0) { + char *pname; + if ((code = krb5_unparse_name(context, kte.principal, + &pname))) { + printerr(0, "WARNING: Skipping keytab entry because " + "we failed to unparse principal name: %s\n", + error_message(code)); + continue; + } + printerr(2, "Processing keytab entry for principal '%s'\n", + pname); + if ( (kte.principal->data[0].length == GSSD_SERVICE_NAME_LEN) && + (strncmp(kte.principal->data[0].data, GSSD_SERVICE_NAME, + GSSD_SERVICE_NAME_LEN) == 0) && + (!gssd_have_realm_ple(&kte.principal->realm)) ) { + printerr(2, "We will use this entry (%s)\n", pname); + ple = malloc(sizeof(struct gssd_k5_kt_princ)); + if (ple == NULL) { + printerr(0, "ERROR: could not allocate storage " + "for principal list entry\n"); + krb5_free_unparsed_name(context, pname); + retval = ENOMEM; + goto out; + } + /* These will be filled in later */ + ple->next = NULL; + ple->ccname = NULL; + ple->endtime = 0; + if ((ple->realm = + strndup(kte.principal->realm.data, + kte.principal->realm.length)) + == NULL) { + printerr(0, "ERROR: %s while copying realm to " + "principal list entry\n", + "not enough memory"); + krb5_free_unparsed_name(context, pname); + retval = ENOMEM; + goto out; + } + if ((code = krb5_copy_principal(context, + kte.principal, &ple->princ))) { + printerr(0, "ERROR: %s while copying principal " + "to principal list entry\n", + error_message(code)); + krb5_free_unparsed_name(context, pname); + retval = code; + goto out; + } + if (gssd_k5_kt_princ_list == NULL) + gssd_k5_kt_princ_list = ple; + else { + ple->next = gssd_k5_kt_princ_list; + gssd_k5_kt_princ_list = ple; + } + } + else { + printerr(2, "We will NOT use this entry (%s)\n", + pname); + } + krb5_free_unparsed_name(context, pname); + } + + if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) { + printerr(0, "WARNING: %s while ending keytab scan for " + "keytab '%s'\n", + error_message(code), kt_name); + } + + retval = 0; + out: + return retval; +} + + +/*==========================*/ +/*=== External routines ===*/ +/*==========================*/ + +/* + * Attempt to find the best match for a credentials cache file + * given only a UID. We really need more information, but we + * do the best we can. + * + * Returns: + * void + */ +void +gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername) +{ + char buf[MAX_NETOBJ_SZ]; +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + u_int min_stat; +#endif + struct dirent *d; + + printerr(2, "getting credentials for client with uid %u for " + "server %s\n", uid, servername); + memset(buf, 0, sizeof(buf)); + if (gssd_find_existing_krb5_ccache(uid, &d)) { + snprintf(buf, sizeof(buf), "FILE:%s/%s", + GSSD_DEFAULT_CRED_DIR, d->d_name); + free(d); + } + else + snprintf(buf, sizeof(buf), "FILE:%s/%s%u", + GSSD_DEFAULT_CRED_DIR, + GSSD_DEFAULT_CRED_PREFIX, uid); + printerr(2, "using %s as credentials cache for client with " + "uid %u for server %s\n", buf, uid, servername); +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + gss_krb5_ccache_name(&min_stat, buf, NULL); +#else + /* + * Set the KRB5CCNAME environment variable to tell the krb5 code + * which credentials cache to use. (Instead of using the private + * function above for which there is no generic gssapi + * equivalent.) + */ + setenv("KRB5CCNAME", buf, 1); +#endif +} + +/* + * Let the gss code know where to find the machine credentials ccache. + * + * Returns: + * void + */ +void +gssd_setup_krb5_machine_gss_ccache(char *ccname) +{ +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + u_int min_stat; +#endif + printerr(2, "using %s as credentials cache for machine creds\n", + ccname); +#ifdef HAVE_GSS_KRB5_CCACHE_NAME + gss_krb5_ccache_name(&min_stat, ccname, NULL); +#else + /* + * Set the KRB5CCNAME environment variable to tell the krb5 code + * which credentials cache to use. (Instead of using the private + * function above for which there is no generic gssapi + * equivalent.) + */ + setenv("KRB5CCNAME", ccname, 1); +#endif +} + +/* + * The first time through this routine, go through the keytab and + * determine which keys we will try to use as machine credentials. + * Every time through this routine, try to obtain credentials using + * the keytab entries selected the first time through. + * + * Returns: + * 0 => obtained one or more credentials + * nonzero => error + * + */ + +int +gssd_refresh_krb5_machine_creds(void) +{ + krb5_context context = NULL; + krb5_keytab kt = NULL;; + krb5_error_code code; + int retval = -1; + struct gssd_k5_kt_princ *ple; + int gotone = 0; + static int processed_keytab = 0; + + + code = krb5_init_context(&context); + if (code) { + printerr(0, "ERROR: %s while initializing krb5 in " + "gssd_refresh_krb5_machine_creds\n", + error_message(code)); + retval = code; + goto out; + } + + printerr(1, "Using keytab file '%s'\n", keytabfile); + + if ((code = krb5_kt_resolve(context, keytabfile, &kt))) { + printerr(0, "ERROR: %s while resolving keytab '%s'\n", + error_message(code), keytabfile); + goto out; + } + + /* Only go through the keytab file once. Only print messages once. */ + if (gssd_k5_kt_princ_list == NULL && !processed_keytab) { + processed_keytab = 1; + gssd_process_krb5_keytab(context, kt, keytabfile); + if (gssd_k5_kt_princ_list == NULL) { + printerr(0, "ERROR: No usable keytab entries found in " + "keytab '%s'\n", keytabfile); + printerr(0, "Do you have a valid keytab entry for " + "%s/@ in " + "keytab file %s ?\n", + GSSD_SERVICE_NAME, keytabfile); + printerr(0, "Continuing without (machine) credentials " + "- nfs4 mounts with Kerberos will fail\n"); + } + } + + /* + * If we don't have any keytab entries we liked, then we have a problem + */ + if (gssd_k5_kt_princ_list == NULL) { + retval = ENOENT; + goto out; + } + + /* + * Now go through the list of saved entries and get initial + * credentials for them (We can't do this while making the + * list because it messes up the keytab iteration cursor + * when we use the keytab to get credentials.) + */ + for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { + if ((gssd_get_single_krb5_cred(context, kt, ple)) == 0) { + gotone++; + } + } + if (!gotone) { + printerr(0, "ERROR: No usable machine credentials obtained\n"); + goto out; + } + + retval = 0; + out: + if (kt) krb5_kt_close(context, kt); + krb5_free_context(context); + + return retval; +} + + +/* + * Return an array of pointers to names of credential cache files + * which can be used to try to create gss contexts with a server. + * + * Returns: + * 0 => list is attached + * nonzero => error + */ +int +gssd_get_krb5_machine_cred_list(char ***list) +{ + char **l; + int listinc = 10; + int listsize = listinc; + int i = 0; + int retval; + struct gssd_k5_kt_princ *ple; + + /* Assume failure */ + retval = -1; + *list = (char **) NULL; + + /* Refresh machine credentials */ + if ((retval = gssd_refresh_krb5_machine_creds())) { + goto out; + } + + if ((l = (char **) malloc(listsize * sizeof(char *))) == NULL) { + retval = ENOMEM; + goto out; + } + + for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { + if (ple->ccname) { + if (i + 1 > listsize) { + listsize += listinc; + l = (char **) + realloc(l, listsize * sizeof(char *)); + if (l == NULL) { + retval = ENOMEM; + goto out; + } + } + if ((l[i++] = strdup(ple->ccname)) == NULL) { + retval = ENOMEM; + goto out; + } + } + } + if (i > 0) { + l[i] = NULL; + *list = l; + retval = 0; + goto out; + } + out: + return retval; +} + +/* + * Frees the list of names returned in get_krb5_machine_cred_list() + */ +void +gssd_free_krb5_machine_cred_list(char **list) +{ + char **n; + + if (list == NULL) + return; + for (n = list; n && *n; n++) { + free(*n); + } + free(list); +} + +/* + * Called upon exit. Destroys machine credentials. + */ +void +gssd_destroy_krb5_machine_creds(void) +{ + krb5_context context; + krb5_error_code code = 0; + krb5_ccache ccache; + struct gssd_k5_kt_princ *ple; + + code = krb5_init_context(&context); + if (code) { + printerr(0, "ERROR: %s while initializing krb5\n", + error_message(code)); + goto out; + } + + for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { + if (!ple->ccname) + continue; + if ((code = krb5_cc_resolve(context, ple->ccname, &ccache))) { + printerr(0, "WARNING: %s while resolving credential " + "cache '%s' for destruction\n", + error_message(code), ple->ccname); + continue; + } + + if ((code = krb5_cc_destroy(context, ccache))) { + printerr(0, "WARNING: %s while destroying credential " + "cache '%s'\n", + error_message(code), ple->ccname); + } + } + out: + krb5_free_context(context); +} + diff -puN /dev/null utils/gssd/krb5_util.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/krb5_util.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,30 @@ +#ifndef KRB5_UTIL_H +#define KRB5_UTIL_H + +#include + +/* + * List of principals from our keytab that we + * may try to get credentials for + */ +struct gssd_k5_kt_princ { + struct gssd_k5_kt_princ *next; + krb5_principal princ; + char *ccname; + char *realm; + krb5_timestamp endtime; +}; + + +void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername); +int gssd_get_krb5_machine_cred_list(char ***list); +int gssd_refresh_krb5_machine_creds(void); +void gssd_free_krb5_machine_cred_list(char **list); +void gssd_setup_krb5_machine_gss_ccache(char *servername); +void gssd_destroy_krb5_machine_creds(void); + +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES +int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid); +#endif + +#endif /* KRB5_UTIL_H */ diff -puN /dev/null utils/gssd/Makefile --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/Makefile 2004-10-27 18:02:50.000000000 -0400 @@ -0,0 +1,15 @@ +# +# Makefile for rpc.gssd +# + +PROGRAM = gssd +PREFIX = rpc. +OBJS = gssd.o gssd_main_loop.o gssd_proc.o err_util.o gss_util.o \ + gss_oids.o context.o context_heimdal.o krb5_util.o +LIBS = -Wl,-rpath=$(KRBDIR)/lib -lrpcsecgss -lgssapi -ldl $(KRBLIB) +MAN8 = gssd + +include $(TOP)rules.mk + +CFLAGS += -DKRB5_VERSION=$(KRB5_VERSION) -I$(TOP)support/rpc/include/ \ + -I$(KRBDIR)/include diff -puN /dev/null utils/gssd/write_bytes.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/gssd/write_bytes.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,139 @@ +/* + Copyright (c) 2004 The Regents of the University of Michigan. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _WRITE_BYTES_H_ +#define _WRITE_BYTES_H_ + +#include +#include +#include /* for ntohl */ + +inline static int +write_bytes(char **ptr, const char *end, const void *arg, int arg_len) +{ + char *p = *ptr, *arg_end; + + arg_end = p + arg_len; + if (arg_end > end || arg_end < p) + return -1; + memcpy(p, arg, arg_len); + *ptr = arg_end; + return 0; +} + +#define WRITE_BYTES(p, end, arg) write_bytes(p, end, &arg, sizeof(arg)) + +inline static int +write_buffer(char **p, char *end, gss_buffer_desc *arg) +{ + if (WRITE_BYTES(p, end, arg->length)) + return -1; + if (*p + arg->length > end) + return -1; + memcpy(*p, arg->value, arg->length); + *p += arg->length; + return 0; +} + +static inline int +get_bytes(char **ptr, const char *end, void *res, int len) +{ + char *p, *q; + p = *ptr; + q = p + len; + if (q > end || q < p) + return -1; + memcpy(res, p, len); + *ptr = q; + return 0; +} + +static inline int +get_buffer(char **ptr, const char *end, gss_buffer_desc *res) +{ + char *p, *q; + p = *ptr; + if (get_bytes(&p, end, &res->length, sizeof(res->length))) + return -1; + q = p + res->length; + if (q > end || q < p) + return -1; + if (!(res->value = malloc(res->length))) + return -1; + memcpy(res->value, p, res->length); + *ptr = q; + return 0; +} + +static inline int +xdr_get_u32(u_int32_t **ptr, const u_int32_t *end, u_int32_t *res) +{ + if (get_bytes((char **)ptr, (char *)end, res, sizeof(res))) + return -1; + *res = ntohl(*res); + return 0; +} + +static inline int +xdr_get_buffer(u_int32_t **ptr, const u_int32_t *end, gss_buffer_desc *res) +{ + u_int32_t *p, *q; + p = *ptr; + if (xdr_get_u32(&p, end, &res->length)) + return -1; + q = p + ((res->length + 3) >> 2); + if (q > end || q < p) + return -1; + if (!(res->value = malloc(res->length))) + return -1; + memcpy(res->value, p, res->length); + *ptr = q; + return 0; +} + +static inline int +xdr_write_u32(u_int32_t **ptr, const u_int32_t *end, u_int32_t arg) +{ + u_int32_t tmp; + + tmp = htonl(arg); + return WRITE_BYTES((char **)ptr, (char *)end, tmp); +} + +static inline int +xdr_write_buffer(u_int32_t **ptr, const u_int32_t *end, gss_buffer_desc *arg) +{ + if (xdr_write_u32(ptr, end, arg->length)) + return -1; + return write_bytes((char **)ptr, (char *)end, arg->value, + (arg->length + 3) & ~3); +} + +#endif /* _WRITE_BYTES_H_ */ diff -puN /dev/null utils/idmapd/atomicio.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/idmapd/atomicio.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2002 Marius Aamodt Eriksen + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +/* + * ensure all of data on socket comes through. f==read || f==write + */ +ssize_t +atomicio(f, fd, _s, n) + ssize_t (*f) (); + int fd; + void *_s; + size_t n; +{ + char *s = _s; + ssize_t res, pos = 0; + + while (n > pos) { + res = (f) (fd, s + pos, n - pos); + switch (res) { + case -1: + if (errno == EINTR || errno == EAGAIN) + continue; + case 0: + if (pos != 0) + return (pos); + return (res); + default: + pos += res; + } + } + return (pos); +} diff -puN /dev/null utils/idmapd/cfg.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/idmapd/cfg.c 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,889 @@ +/* $OpenBSD: conf.c,v 1.55 2003/06/03 14:28:16 ho Exp $ */ +/* $EOM: conf.c,v 1.48 2000/12/04 02:04:29 angelos Exp $ */ + +/* + * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved. + * Copyright (c) 2000, 2001, 2002 Håkan Olsson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code was written under funding by Ericsson Radio Systems. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cfg.h" + +static void conf_load_defaults (int); +#if 0 +static int conf_find_trans_xf (int, char *); +#endif + +size_t strlcpy(char *, const char *, size_t); + +struct conf_trans { + TAILQ_ENTRY (conf_trans) link; + int trans; + enum conf_op { CONF_SET, CONF_REMOVE, CONF_REMOVE_SECTION } op; + char *section; + char *tag; + char *value; + int override; + int is_default; +}; + +TAILQ_HEAD (conf_trans_head, conf_trans) conf_trans_queue; + +/* + * Radix-64 Encoding. + */ +const u_int8_t bin2asc[] + = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +const u_int8_t asc2bin[] = +{ + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 255, 255, 255, 255, 255, 255, + 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 255, 255, 255, 255, 255, + 255, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255 +}; + +struct conf_binding { + LIST_ENTRY (conf_binding) link; + char *section; + char *tag; + char *value; + int is_default; +}; + +char *conf_path; +LIST_HEAD (conf_bindings, conf_binding) conf_bindings[256]; + +static char *conf_addr; + +static __inline__ u_int8_t +conf_hash (char *s) +{ + u_int8_t hash = 0; + + while (*s) + { + hash = ((hash << 1) | (hash >> 7)) ^ tolower (*s); + s++; + } + return hash; +} + +/* + * Insert a tag-value combination from LINE (the equal sign is at POS) + */ +static int +conf_remove_now (char *section, char *tag) +{ + struct conf_binding *cb, *next; + + for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb; cb = next) + { + next = LIST_NEXT (cb, link); + if (strcasecmp (cb->section, section) == 0 + && strcasecmp (cb->tag, tag) == 0) + { + LIST_REMOVE (cb, link); + warnx("[%s]:%s->%s removed", section, tag, cb->value); + free (cb->section); + free (cb->tag); + free (cb->value); + free (cb); + return 0; + } + } + return 1; +} + +static int +conf_remove_section_now (char *section) +{ + struct conf_binding *cb, *next; + int unseen = 1; + + for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb; cb = next) + { + next = LIST_NEXT (cb, link); + if (strcasecmp (cb->section, section) == 0) + { + unseen = 0; + LIST_REMOVE (cb, link); + warnx("[%s]:%s->%s removed", section, cb->tag, cb->value); + free (cb->section); + free (cb->tag); + free (cb->value); + free (cb); + } + } + return unseen; +} + +/* + * Insert a tag-value combination from LINE (the equal sign is at POS) + * into SECTION of our configuration database. + */ +static int +conf_set_now (char *section, char *tag, char *value, int override, + int is_default) +{ + struct conf_binding *node = 0; + + if (override) + conf_remove_now (section, tag); + else if (conf_get_str (section, tag)) + { + if (!is_default) + warnx("conf_set: duplicate tag [%s]:%s, ignoring...\n", section, tag); + return 1; + } + + node = calloc (1, sizeof *node); + if (!node) + { + warnx("conf_set: calloc (1, %lu) failed", (unsigned long)sizeof *node); + return 1; + } + node->section = strdup (section); + node->tag = strdup (tag); + node->value = strdup (value); + node->is_default = is_default; + + LIST_INSERT_HEAD (&conf_bindings[conf_hash (section)], node, link); + return 0; +} + +/* + * Parse the line LINE of SZ bytes. Skip Comments, recognize section + * headers and feed tag-value pairs into our configuration database. + */ +static void +conf_parse_line (int trans, char *line, size_t sz) +{ + char *val; + size_t i; + int j; + static char *section = 0; + static int ln = 0; + + ln++; + + /* Lines starting with '#' or ';' are comments. */ + if (*line == '#' || *line == ';') + return; + + /* '[section]' parsing... */ + if (*line == '[') + { + for (i = 1; i < sz; i++) + if (line[i] == ']') + break; + if (section) + free (section); + if (i == sz) + { + warnx("conf_parse_line: %d:" + "non-matched ']', ignoring until next section", ln); + section = 0; + return; + } + section = malloc (i); + if (!section) + { + warnx("conf_parse_line: %d: malloc (%lu) failed", ln, + (unsigned long)i); + return; + } + strlcpy (section, line + 1, i); + return; + } + + /* Deal with assignments. */ + for (i = 0; i < sz; i++) + if (line[i] == '=') + { + /* If no section, we are ignoring the lines. */ + if (!section) + { + warnx("conf_parse_line: %d: ignoring line due to no section", ln); + return; + } + line[strcspn (line, " \t=")] = '\0'; + val = line + i + 1 + strspn (line + i + 1, " \t"); + /* Skip trailing whitespace, if any */ + for (j = sz - (val - line) - 1; j > 0 && isspace (val[j]); j--) + val[j] = '\0'; + /* XXX Perhaps should we not ignore errors? */ + conf_set (trans, section, line, val, 0, 0); + return; + } + + /* Other non-empty lines are weird. */ + i = strspn (line, " \t"); + if (line[i]) + warnx("conf_parse_line: %d: syntax error", ln); + + return; +} + +/* Parse the mapped configuration file. */ +static void +conf_parse (int trans, char *buf, size_t sz) +{ + char *cp = buf; + char *bufend = buf + sz; + char *line; + + line = cp; + while (cp < bufend) + { + if (*cp == '\n') + { + /* Check for escaped newlines. */ + if (cp > buf && *(cp - 1) == '\\') + *(cp - 1) = *cp = ' '; + else + { + *cp = '\0'; + conf_parse_line (trans, line, cp - line); + line = cp + 1; + } + } + cp++; + } + if (cp != line) + warnx("conf_parse: last line non-terminated, ignored."); +} + +static void +conf_load_defaults (int tr) +{ + /* No defaults */ + return; +} + +void +conf_init (void) +{ + unsigned int i; + + for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++) + LIST_INIT (&conf_bindings[i]); + TAILQ_INIT (&conf_trans_queue); + conf_reinit (); +} + +/* Open the config file and map it into our address space, then parse it. */ +void +conf_reinit (void) +{ + struct conf_binding *cb = 0; + int fd, trans; + unsigned int i; + size_t sz; + char *new_conf_addr = 0; + struct stat sb; + + if ((stat (conf_path, &sb) == 0) || (errno != ENOENT)) + { + sz = sb.st_size; + fd = open (conf_path, O_RDONLY, 0); + if (fd == -1) + { + warnx("conf_reinit: open (\"%s\", O_RDONLY) failed", conf_path); + return; + } + + new_conf_addr = malloc (sz); + if (!new_conf_addr) + { + warnx("conf_reinit: malloc (%lu) failed", (unsigned long)sz); + goto fail; + } + + /* XXX I assume short reads won't happen here. */ + if (read (fd, new_conf_addr, sz) != (int)sz) + { + warnx("conf_reinit: read (%d, %p, %lu) failed", + fd, new_conf_addr, (unsigned long)sz); + goto fail; + } + close (fd); + + trans = conf_begin (); + + /* XXX Should we not care about errors and rollback? */ + conf_parse (trans, new_conf_addr, sz); + } + else + trans = conf_begin (); + + /* Load default configuration values. */ + conf_load_defaults (trans); + + /* Free potential existing configuration. */ + if (conf_addr) + { + for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++) + for (cb = LIST_FIRST (&conf_bindings[i]); cb; + cb = LIST_FIRST (&conf_bindings[i])) + conf_remove_now (cb->section, cb->tag); + free (conf_addr); + } + + conf_end (trans, 1); + conf_addr = new_conf_addr; + return; + + fail: + if (new_conf_addr) + free (new_conf_addr); + close (fd); +} + +/* + * Return the numeric value denoted by TAG in section SECTION or DEF + * if that tag does not exist. + */ +int +conf_get_num (char *section, char *tag, int def) +{ + char *value = conf_get_str (section, tag); + + if (value) + return atoi (value); + return def; +} + +/* Validate X according to the range denoted by TAG in section SECTION. */ +int +conf_match_num (char *section, char *tag, int x) +{ + char *value = conf_get_str (section, tag); + int val, min, max, n; + + if (!value) + return 0; + n = sscanf (value, "%d,%d:%d", &val, &min, &max); + switch (n) + { + case 1: + warnx("conf_match_num: %s:%s %d==%d?", section, tag, val, x); + return x == val; + case 3: + warnx("conf_match_num: %s:%s %d<=%d<=%d?", section, tag, min, x, max); + return min <= x && max >= x; + default: + warnx("conf_match_num: section %s tag %s: invalid number spec %s", + section, tag, value); + } + return 0; +} + +/* Return the string value denoted by TAG in section SECTION. */ +char * +conf_get_str (char *section, char *tag) +{ + struct conf_binding *cb; + + for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb; + cb = LIST_NEXT (cb, link)) + if (strcasecmp (section, cb->section) == 0 + && strcasecmp (tag, cb->tag) == 0) + { + return cb->value; + } + return 0; +} + +/* + * Build a list of string values out of the comma separated value denoted by + * TAG in SECTION. + */ +struct conf_list * +conf_get_list (char *section, char *tag) +{ + char *liststr = 0, *p, *field, *t; + struct conf_list *list = 0; + struct conf_list_node *node; + + list = malloc (sizeof *list); + if (!list) + goto cleanup; + TAILQ_INIT (&list->fields); + list->cnt = 0; + liststr = conf_get_str (section, tag); + if (!liststr) + goto cleanup; + liststr = strdup (liststr); + if (!liststr) + goto cleanup; + p = liststr; + while ((field = strsep (&p, ",")) != NULL) + { + /* Skip leading whitespace */ + while (isspace (*field)) + field++; + /* Skip trailing whitespace */ + if (p) + for (t = p - 1; t > field && isspace (*t); t--) + *t = '\0'; + if (*field == '\0') + { + warnx("conf_get_list: empty field, ignoring..."); + continue; + } + list->cnt++; + node = calloc (1, sizeof *node); + if (!node) + goto cleanup; + node->field = strdup (field); + if (!node->field) + goto cleanup; + TAILQ_INSERT_TAIL (&list->fields, node, link); + } + free (liststr); + return list; + + cleanup: + if (list) + conf_free_list (list); + if (liststr) + free (liststr); + return 0; +} + +struct conf_list * +conf_get_tag_list (char *section) +{ + struct conf_list *list = 0; + struct conf_list_node *node; + struct conf_binding *cb; + + list = malloc (sizeof *list); + if (!list) + goto cleanup; + TAILQ_INIT (&list->fields); + list->cnt = 0; + for (cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); cb; + cb = LIST_NEXT (cb, link)) + if (strcasecmp (section, cb->section) == 0) + { + list->cnt++; + node = calloc (1, sizeof *node); + if (!node) + goto cleanup; + node->field = strdup (cb->tag); + if (!node->field) + goto cleanup; + TAILQ_INSERT_TAIL (&list->fields, node, link); + } + return list; + + cleanup: + if (list) + conf_free_list (list); + return 0; +} + +/* Decode a PEM encoded buffer. */ +int +conf_decode_base64 (u_int8_t *out, u_int32_t *len, u_char *buf) +{ + u_int32_t c = 0; + u_int8_t c1, c2, c3, c4; + + while (*buf) + { + if (*buf > 127 || (c1 = asc2bin[*buf]) == 255) + return 0; + buf++; + + if (*buf > 127 || (c2 = asc2bin[*buf]) == 255) + return 0; + buf++; + + if (*buf == '=') + { + c3 = c4 = 0; + c++; + + /* Check last four bit */ + if (c2 & 0xF) + return 0; + + if (strcmp ((char *)buf, "==") == 0) + buf++; + else + return 0; + } + else if (*buf > 127 || (c3 = asc2bin[*buf]) == 255) + return 0; + else + { + if (*++buf == '=') + { + c4 = 0; + c += 2; + + /* Check last two bit */ + if (c3 & 3) + return 0; + + if (strcmp ((char *)buf, "=")) + return 0; + + } + else if (*buf > 127 || (c4 = asc2bin[*buf]) == 255) + return 0; + else + c += 3; + } + + buf++; + *out++ = (c1 << 2) | (c2 >> 4); + *out++ = (c2 << 4) | (c3 >> 2); + *out++ = (c3 << 6) | c4; + } + + *len = c; + return 1; + +} + +void +conf_free_list (struct conf_list *list) +{ + struct conf_list_node *node = TAILQ_FIRST (&list->fields); + + while (node) + { + TAILQ_REMOVE (&list->fields, node, link); + if (node->field) + free (node->field); + free (node); + node = TAILQ_FIRST (&list->fields); + } + free (list); +} + +int +conf_begin (void) +{ + static int seq = 0; + + return ++seq; +} + +static struct conf_trans * +conf_trans_node (int transaction, enum conf_op op) +{ + struct conf_trans *node; + + node = calloc (1, sizeof *node); + if (!node) + { + warnx("conf_trans_node: calloc (1, %lu) failed", + (unsigned long)sizeof *node); + return 0; + } + node->trans = transaction; + node->op = op; + TAILQ_INSERT_TAIL (&conf_trans_queue, node, link); + return node; +} + +/* Queue a set operation. */ +int +conf_set (int transaction, char *section, char *tag, char *value, int override, + int is_default) +{ + struct conf_trans *node; + + node = conf_trans_node (transaction, CONF_SET); + if (!node) + return 1; + node->section = strdup (section); + if (!node->section) + { + warnx("conf_set: strdup (\"%s\") failed", section); + goto fail; + } + node->tag = strdup (tag); + if (!node->tag) + { + warnx("conf_set: strdup (\"%s\") failed", tag); + goto fail; + } + node->value = strdup (value); + if (!node->value) + { + warnx("conf_set: strdup (\"%s\") failed", value); + goto fail; + } + node->override = override; + node->is_default = is_default; + return 0; + + fail: + if (node->tag) + free (node->tag); + if (node->section) + free (node->section); + if (node) + free (node); + return 1; +} + +/* Queue a remove operation. */ +int +conf_remove (int transaction, char *section, char *tag) +{ + struct conf_trans *node; + + node = conf_trans_node (transaction, CONF_REMOVE); + if (!node) + goto fail; + node->section = strdup (section); + if (!node->section) + { + warnx("conf_remove: strdup (\"%s\") failed", section); + goto fail; + } + node->tag = strdup (tag); + if (!node->tag) + { + warnx("conf_remove: strdup (\"%s\") failed", tag); + goto fail; + } + return 0; + + fail: + if (node->section) + free (node->section); + if (node) + free (node); + return 1; +} + +/* Queue a remove section operation. */ +int +conf_remove_section (int transaction, char *section) +{ + struct conf_trans *node; + + node = conf_trans_node (transaction, CONF_REMOVE_SECTION); + if (!node) + goto fail; + node->section = strdup (section); + if (!node->section) + { + warnx("conf_remove_section: strdup (\"%s\") failed", section); + goto fail; + } + return 0; + + fail: + if (node) + free (node); + return 1; +} + +/* Execute all queued operations for this transaction. Cleanup. */ +int +conf_end (int transaction, int commit) +{ + struct conf_trans *node, *next; + + for (node = TAILQ_FIRST (&conf_trans_queue); node; node = next) + { + next = TAILQ_NEXT (node, link); + if (node->trans == transaction) + { + if (commit) + switch (node->op) + { + case CONF_SET: + conf_set_now (node->section, node->tag, node->value, + node->override, node->is_default); + break; + case CONF_REMOVE: + conf_remove_now (node->section, node->tag); + break; + case CONF_REMOVE_SECTION: + conf_remove_section_now (node->section); + break; + default: + warnx("conf_end: unknown operation: %d", node->op); + } + TAILQ_REMOVE (&conf_trans_queue, node, link); + if (node->section) + free (node->section); + if (node->tag) + free (node->tag); + if (node->value) + free (node->value); + free (node); + } + } + return 0; +} + +/* + * Dump running configuration upon SIGUSR1. + * Configuration is "stored in reverse order", so reverse it again. + */ +struct dumper { + char *s, *v; + struct dumper *next; +}; + +static void +conf_report_dump (struct dumper *node) +{ + /* Recursive, cleanup when we're done. */ + + if (node->next) + conf_report_dump (node->next); + + if (node->v) + warnx("%s=\t%s", node->s, node->v); + else if (node->s) + { + warnx("%s", node->s); + if (strlen (node->s) > 0) + free (node->s); + } + + free (node); +} + +void +conf_report (void) +{ + struct conf_binding *cb, *last = 0; + unsigned int i, len; + char *current_section = (char *)0; + struct dumper *dumper, *dnode; + + dumper = dnode = (struct dumper *)calloc (1, sizeof *dumper); + if (!dumper) + goto mem_fail; + + warnx("conf_report: dumping running configuration"); + + for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++) + for (cb = LIST_FIRST (&conf_bindings[i]); cb; + cb = LIST_NEXT (cb, link)) + { + if (!cb->is_default) + { + /* Dump this entry. */ + if (!current_section || strcmp (cb->section, current_section)) + { + if (current_section) + { + len = strlen (current_section) + 3; + dnode->s = malloc (len); + if (!dnode->s) + goto mem_fail; + + snprintf (dnode->s, len, "[%s]", current_section); + dnode->next + = (struct dumper *)calloc (1, sizeof (struct dumper)); + dnode = dnode->next; + if (!dnode) + goto mem_fail; + + dnode->s = ""; + dnode->next + = (struct dumper *)calloc (1, sizeof (struct dumper)); + dnode = dnode->next; + if (!dnode) + goto mem_fail; + } + current_section = cb->section; + } + dnode->s = cb->tag; + dnode->v = cb->value; + dnode->next = (struct dumper *)calloc (1, sizeof (struct dumper)); + dnode = dnode->next; + if (!dnode) + goto mem_fail; + last = cb; + } + } + + if (last) + { + len = strlen (last->section) + 3; + dnode->s = malloc (len); + if (!dnode->s) + goto mem_fail; + snprintf (dnode->s, len, "[%s]", last->section); + } + + conf_report_dump (dumper); + + return; + + mem_fail: + warnx("conf_report: malloc/calloc failed"); + while ((dnode = dumper) != 0) + { + dumper = dumper->next; + if (dnode->s) + free (dnode->s); + free (dnode); + } + return; +} diff -puN /dev/null utils/idmapd/cfg.h --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/idmapd/cfg.h 2004-10-27 18:02:49.000000000 -0400 @@ -0,0 +1,67 @@ +/* $OpenBSD: conf.h,v 1.30 2004/06/25 20:25:34 hshoexer Exp $ */ +/* $EOM: conf.h,v 1.13 2000/09/18 00:01:47 ho Exp $ */ + +/* + * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved. + * Copyright (c) 2000, 2003 Håkan Olsson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code was written under funding by Ericsson Radio Systems. + */ + +#ifndef _CONF_H_ +#define _CONF_H_ + +#include "queue.h" + +struct conf_list_node { + TAILQ_ENTRY(conf_list_node) link; + char *field; +}; + +struct conf_list { + size_t cnt; + TAILQ_HEAD(conf_list_fields_head, conf_list_node) fields; +}; + +extern char *conf_path; + +extern int conf_begin(void); +extern int conf_decode_base64(u_int8_t *, u_int32_t *, u_char *); +extern int conf_end(int, int); +extern void conf_free_list(struct conf_list *); +extern struct sockaddr *conf_get_address(char *, char *); +extern struct conf_list *conf_get_list(char *, char *); +extern struct conf_list *conf_get_tag_list(char *); +extern int conf_get_num(char *, char *, int); +extern char *conf_get_str(char *, char *); +extern void conf_init(void); +extern int conf_match_num(char *, char *, int); +extern void conf_reinit(void); +extern int conf_remove(int, char *, char *); +extern int conf_remove_section(int, char *); +extern int conf_set(int, char *, char *, char *, int, int); +extern void conf_report(void); + +#endif /* _CONF_H_ */ diff -puN /dev/null utils/idmapd/idmapd.c --- /dev/null 2004-08-19 17:44:20.000000000 -0400 +++ nfs-utils-1.0.6-bfields/utils/idmapd/idmapd.c 2004-10-27 18:02:50.000000000 -0400 @@ -0,0 +1,884 @@ +/* + * idmapd.c + * + * Userland daemon for idmap. + * + * Copyright (c) 2002 The Regents of the University of Michigan. + * All rights reserved. + * + * Marius Aamodt Eriksen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY