+2005-08-26 Kevin Coffman <kwc@citi.umich.edu>
+       *utils/mountd/mountd.c:
+       mountd currently always returns AUTH_NULL and AUTH_SYS as the
+       allowable flavors in mount replies.  We want it to also return gss
+       flavors when appropriate. For now as a hack we just have it always
+       return the KRB5 flavors as well. 
+
+       *utils/mountd/cache.c:
+       
+       When attempting to mount an NFSv4 pseudofilesystem (fsid=0) and the
+       actual exported directory does not exist on the server, rpc.mountd
+       doesn't check the directory exists (when fsidtype=1, i.e. using fsid,
+       but does check for fsidtype=0, i.e. using dev/ino).  The non-existent
+       exported directory path with fsid=0 is written to the kernel via
+       /proc/net/rpc/nfsd.export/channel, which leads to path_lookup() to
+       return ENOENT (seems appropriate).  Unfortunately, the new_cache
+       approach ignores errors returned when writing via the channel file so
+       that particular error is lost and the mount request is silently ignored.
+       
+       Assuming it doesn't make sense to revamp the new_cache/up-call method to
+       not ignore returned errors, it seems appropriate to fix the case where
+       rpc.mountd doesn't check for the existence of an exported directory with
+       fsid= semantics.  The following patch does this by moving the stat() up
+       so it is done for both fsidtype's.  I'm not certain whether the other
+       tests need to be executed for fsidtype=1, but it doesn't appear to hurt
+       [Not exactly true: the comparison of inode numbers caused problems so
+       now it's kept for fsidtype=0 only].
+       
+       Would it be also desirable to log a warning for every error, if any,
+       returned by a write to any of the /proc/net/rpc/*/channel files which
+       would otherwise be ignored (maybe under a debug flag)?
+
+       * gssd/mountd/svcgssd: Changes gssd, svcgssd, and mountd to ignore a
+       SIGHUP rather than dying.
+
+       * many: Remove the gssapi code and rely on an external library instead.
+
 2005-08-26 Kevin Coffman <kwc@citi.umich.edu>
        * utils/exportfs/exports.man: Document the "crossmnt" export export option
        * utils/gssd/krb5_util.c: 
 
 /etc/default/nfs-common
 /etc/init.d/nfs-common
 /etc/idmapd.conf
-/etc/gssapi_mech.conf
 
 debian/idmapd.conf etc
-debian/gssapi_mech.conf etc
 
-#
-# libgssapi.a
-# gssapi mechanism-switching layer
-#
-TOP    = ../../
-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::
-       @:
 
 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
-LIBDEPS        = $(TOP)support/lib/librpc.a $(TOP)support/lib/libgssapi.a
+LIBDEPS        = $(TOP)support/lib/librpc.a
 LIBS   = -Wl,-rpath=$(KRBDIR)/lib -lrpc -lgssapi -ldl $(KRBLIB)
 MAN8   = gssd
 
 
        exit(1);
 }
 
+void
+sig_hup(int signal)
+{
+       /* don't exit on SIGHUP */
+       printerr(1, "Received SIGHUP... Ignoring.\n");
+       return;
+}
+
 static void
 usage(char *progname)
 {
 
        signal(SIGINT, sig_die);
        signal(SIGTERM, sig_die);
-       signal(SIGHUP, sig_die);
+       signal(SIGHUP, sig_hup);
 
        /* Process keytab file and get machine credentials */
        gssd_refresh_krb5_machine_creds();
 
        /* Now determine export point for this fsid/domain */
        for (i=0 ; i < MCL_MAXTYPES; i++) {
                for (exp = exportlist[i]; exp; exp = exp->m_next) {
+                       struct stat stb;
+
                        if (!client_member(dom, exp->m_client->m_hostname))
                                continue;
+                       if (exp->m_export.e_mountpoint &&
+                           !is_mountpoint(exp->m_export.e_mountpoint[0]?
+                                          exp->m_export.e_mountpoint:
+                                          exp->m_export.e_path))
+                               dev_missing ++;
+                       if (stat(exp->m_export.e_path, &stb) != 0)
+                               continue;
                        if (fsidtype == 1 &&
                            ((exp->m_export.e_flags & NFSEXP_FSID) == 0 ||
                             exp->m_export.e_fsid != fsidnum))
                                continue;
                        if (fsidtype == 0) {
-                               struct stat stb;
-                               if (exp->m_export.e_mountpoint &&
-                                   !is_mountpoint(exp->m_export.e_mountpoint[0]?
-                                                  exp->m_export.e_mountpoint:
-                                                  exp->m_export.e_path))
-                                       dev_missing ++;
-                               if (stat(exp->m_export.e_path, &stb) != 0)
-                                       continue;
                                if (stb.st_ino != inode)
                                        continue;
                                if (major != major(stb.st_dev) ||
 
   xlog (L_FATAL, "Caught signal %d, un-registering and exiting.", sig);
 }
 
+static void
+sig_hup (int sig)
+{
+  /* don't exit on SIGHUP */
+  xlog (L_NOTICE, "Received SIGHUP... Ignoring.\n", sig);
+  return;
+}
+
 bool_t
 mount_null_1_svc(struct svc_req *rqstp, void *argp, void *resp)
 {
 bool_t
 mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res)
 {
-       static int      flavors[] = { AUTH_NULL, AUTH_UNIX };
+#define AUTH_GSS_KRB5 390003
+#define AUTH_GSS_KRB5I 390004
+#define AUTH_GSS_KRB5P 390005
+       static int      flavors[] = { AUTH_NULL, AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P};
        struct nfs_fh_len *fh;
 
        xlog(D_CALL, "MNT3(%s) called", *path);
 
                ok->fhandle.fhandle3_len = fh->fh_size;
                ok->fhandle.fhandle3_val = fh->fh_handle;
-               ok->auth_flavors.auth_flavors_len = 2;
+               ok->auth_flavors.auth_flavors_len
+                       = sizeof(flavors)/sizeof(flavors[0]);
                ok->auth_flavors.auth_flavors_val = flavors;
        }
        return 1;
                         mount_dispatch, port);
 
        sa.sa_handler = killer;
-       sigaction(SIGHUP, &sa, NULL);
        sigaction(SIGINT, &sa, NULL);
        sigaction(SIGTERM, &sa, NULL);
+       sa.sa_handler = sig_hup;
+       sigaction(SIGHUP, &sa, NULL);
 
        auth_init(export_file);
 
 
 PREFIX = rpc.
 OBJS   = svcgssd.o svcgssd_main_loop.o svcgssd_proc.o err_util.o gss_util.o \
          gss_oids.o context.o context_heimdal.o cacheio.o svcgssd_mech2file.o
-LIBDEPS        = $(TOP)support/lib/librpc.a $(TOP)support/lib/libgssapi.a
+LIBDEPS        = $(TOP)support/lib/librpc.a
 LIBS   = -Wl,-rpath=$(KRBDIR)/lib -lrpc -lgssapi -ldl $(KRBLIB) -lnfsidmap
 MAN8   = svcgssd
 
 
        exit(1);
 }
 
+void
+sig_hup(int signal)
+{
+       /* don't exit on SIGHUP */
+       printerr(1, "Received SIGHUP... Ignoring.\n");
+       return;
+}
+
 static void
 usage(char *progname)
 {
 
        signal(SIGINT, sig_die);
        signal(SIGTERM, sig_die);
-       signal(SIGHUP, sig_die);
+       signal(SIGHUP, sig_hup);
 
        if (get_creds && !gssd_acquire_cred(GSSD_SERVICE_NAME)) {
                 printerr(0, "unable to obtain root (machine) credentials\n");