update for version 3 from Rick Macklem
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Thu, 30 Mar 1995 13:57:51 +0000 (05:57 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Thu, 30 Mar 1995 13:57:51 +0000 (05:57 -0800)
SCCS-vsn: sbin/nfsd/nfsd.c 8.9
SCCS-vsn: sbin/nfsd/nfsd.8 8.4
SCCS-vsn: usr.bin/showmount/showmount.c 8.3
SCCS-vsn: usr.bin/showmount/showmount.c 8.3
SCCS-vsn: usr.bin/showmount/showmount.8 8.3

usr/src/sbin/nfsd/nfsd.8
usr/src/sbin/nfsd/nfsd.c
usr/src/usr.bin/showmount/showmount.8
usr/src/usr.bin/showmount/showmount.c

index fd9eb8f..8f95dde 100644 (file)
@@ -3,7 +3,7 @@
 .\"
 .\" %sccs.include.redist.roff%
 .\"
 .\"
 .\" %sccs.include.redist.roff%
 .\"
-.\"    @(#)nfsd.8      8.3 (Berkeley) %G%
+.\"    @(#)nfsd.8      8.4 (Berkeley) %G%
 .\"
 .Dd 
 .Dt NFSD 8
 .\"
 .Dd 
 .Dt NFSD 8
@@ -72,7 +72,8 @@ listens for service requests at the port indicated in the
 .Tn NFS
 server specification; see
 .%T "Network File System Protocol Specification" ,
 .Tn NFS
 server specification; see
 .%T "Network File System Protocol Specification" ,
-RFC1094.
+RFC1094 and
+.%T "NFS: Network File System Version 3 Protocol Specification" .
 .Pp
 The
 .Nm nfsd
 .Pp
 The
 .Nm nfsd
index 1b37045..f6ca031 100644 (file)
@@ -15,7 +15,7 @@ static char copyright[] =
 #endif not lint
 
 #ifndef lint
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)nfsd.c     8.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)nfsd.c     8.9 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/param.h>
 #endif not lint
 
 #include <sys/param.h>
@@ -37,10 +37,10 @@ static char sccsid[] = "@(#)nfsd.c  8.8 (Berkeley) %G%";
 #include <netiso/iso.h>
 #endif
 #include <nfs/rpcv2.h>
 #include <netiso/iso.h>
 #endif
 #include <nfs/rpcv2.h>
-#include <nfs/nfsv2.h>
+#include <nfs/nfsproto.h>
 #include <nfs/nfs.h>
 
 #include <nfs/nfs.h>
 
-#ifdef KERBEROS
+#ifdef NFSKERB
 #include <kerberosIV/des.h>
 #include <kerberosIV/krb.h>
 #endif
 #include <kerberosIV/des.h>
 #include <kerberosIV/krb.h>
 #endif
@@ -68,11 +68,16 @@ struct      nfsd_srvargs nsd;
 char   **Argv = NULL;          /* pointer to argument vector */
 char   *LastArg = NULL;        /* end of argv */
 
 char   **Argv = NULL;          /* pointer to argument vector */
 char   *LastArg = NULL;        /* end of argv */
 
-#ifdef KERBEROS
+#ifdef NFSKERB
 char           lnam[ANAME_SZ];
 KTEXT_ST       kt;
 char           lnam[ANAME_SZ];
 KTEXT_ST       kt;
-AUTH_DAT       auth;
+AUTH_DAT       kauth;
 char           inst[INST_SZ];
 char           inst[INST_SZ];
+struct nfsrpc_fullblock kin, kout;
+struct nfsrpc_fullverf kverf;
+NFSKERBKEY_T   kivec;
+struct timeval ktv;
+NFSKERBKEYSCHED_T kerb_keysched;
 #endif
 
 void   nonfs __P((int));
 #endif
 
 void   nonfs __P((int));
@@ -113,6 +118,7 @@ main(argc, argv, envp)
 #ifdef ISO
        struct sockaddr_iso isoaddr, isopeer;
 #endif
 #ifdef ISO
        struct sockaddr_iso isoaddr, isopeer;
 #endif
+       struct timeval ktv;
        fd_set ready, sockbits;
        int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
        int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock;
        fd_set ready, sockbits;
        int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
        int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock;
@@ -203,10 +209,12 @@ main(argc, argv, envp)
 
        if (reregister) {
                if (udpflag &&
 
        if (reregister) {
                if (udpflag &&
-                   !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT))
+                   (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
+                    !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)))
                        err(1, "can't register with portmap for UDP.");
                if (tcpflag &&
                        err(1, "can't register with portmap for UDP.");
                if (tcpflag &&
-                   !pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT))
+                   (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
+                    !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)))
                        err(1, "can't register with portmap for TCP.");
                exit(0);
        }
                        err(1, "can't register with portmap for TCP.");
                exit(0);
        }
@@ -223,11 +231,17 @@ main(argc, argv, envp)
                        continue;
                }
 
                        continue;
                }
 
-               setproctitle("nfsd-srv");
+               setproctitle("server");
                nfssvc_flag = NFSSVC_NFSD;
                nsd.nsd_nfsd = NULL;
                nfssvc_flag = NFSSVC_NFSD;
                nsd.nsd_nfsd = NULL;
-#ifdef KERBEROS
-               nsd.nsd_authstr = (char *)kt.dat;
+#ifdef NFSKERB
+               if (sizeof (struct nfsrpc_fullverf) != RPCX_FULLVERF ||
+                   sizeof (struct nfsrpc_fullblock) != RPCX_FULLBLOCK)
+                   syslog(LOG_ERR, "Yikes NFSKERB structs not packed!");
+               nsd.nsd_authstr = (u_char *)&kt;
+               nsd.nsd_authlen = sizeof (kt);
+               nsd.nsd_verfstr = (u_char *)&kverf;
+               nsd.nsd_verflen = sizeof (kverf);
 #endif
                while (nfssvc(nfssvc_flag, &nsd) < 0) {
                        if (errno != ENEEDAUTH) {
 #endif
                while (nfssvc(nfssvc_flag, &nsd) < 0) {
                        if (errno != ENEEDAUTH) {
@@ -235,14 +249,27 @@ main(argc, argv, envp)
                                exit(1);
                        }
                        nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
                                exit(1);
                        }
                        nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHINFAIL;
-#ifdef KERBEROS
-                       kt.length = nsd.nsd_authlen;
-                       kt.mbz = 0;
-                       (void)strcpy(inst, "*");
-                       if (krb_rd_req(&kt, "rcmd",
-                           inst, nsd.nsd_haddr, &auth, "") == RD_AP_OK &&
-                           krb_kntoln(&auth, lnam) == KSUCCESS &&
-                           (pwd = getpwnam(lnam)) != NULL) {
+#ifdef NFSKERB
+                       /*
+                        * Get the Kerberos ticket out of the authenticator
+                        * verify it and convert the principal name to a user
+                        * name. The user name is then converted to a set of
+                        * user credentials via the password and group file.
+                        * Finally, decrypt the timestamp and validate it.
+                        * For more info see the IETF Draft "Authentication
+                        * in ONC RPC".
+                        */
+                       kt.length = ntohl(kt.length);
+                       if (gettimeofday(&ktv, (struct timezone *)0) == 0 &&
+                           kt.length > 0 && kt.length <=
+                           (RPCAUTH_MAXSIZ - 3 * NFSX_UNSIGNED)) {
+                           kin.w1 = NFS_KERBW1(kt);
+                           kt.mbz = 0;
+                           (void)strcpy(inst, "*");
+                           if (krb_rd_req(&kt, NFS_KERBSRV,
+                               inst, nsd.nsd_haddr, &kauth, "") == RD_AP_OK &&
+                               krb_kntoln(&kauth, lnam) == KSUCCESS &&
+                               (pwd = getpwnam(lnam)) != NULL) {
                                cr = &nsd.nsd_cr;
                                cr->cr_uid = pwd->pw_uid;
                                cr->cr_groups[0] = pwd->pw_gid;
                                cr = &nsd.nsd_cr;
                                cr->cr_uid = pwd->pw_uid;
                                cr->cr_groups[0] = pwd->pw_gid;
@@ -263,9 +290,34 @@ main(argc, argv, envp)
                                                break;
                                }
                                endgrent();
                                                break;
                                }
                                endgrent();
-                               nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN;
+
+                               /*
+                                * Get the timestamp verifier out of the
+                                * authenticator and verifier strings.
+                                */
+                               kin.t1 = kverf.t1;
+                               kin.t2 = kverf.t2;
+                               kin.w2 = kverf.w2;
+                               bzero((caddr_t)kivec, sizeof (kivec));
+                               bcopy((caddr_t)kauth.session,
+                                   (caddr_t)nsd.nsd_key,sizeof(kauth.session));
+
+                               /*
+                                * Decrypt the timestamp verifier in CBC mode.
+                                */
+                               XXX
+
+                               /*
+                                * Validate the timestamp verifier, to
+                                * check that the session key is ok.
+                                */
+                               nsd.nsd_timestamp.tv_sec = ntohl(kout.t1);
+                               nsd.nsd_timestamp.tv_usec = ntohl(kout.t2);
+                               nsd.nsd_ttl = ntohl(kout.w1);
+                               if ((nsd.nsd_ttl - 1) == ntohl(kout.w2))
+                                   nfssvc_flag = NFSSVC_NFSD | NFSSVC_AUTHIN;
                        }
                        }
-#endif /* KERBEROS */
+#endif /* NFSKERB */
                }
                exit(0);
        }
                }
                exit(0);
        }
@@ -285,7 +337,8 @@ main(argc, argv, envp)
                        syslog(LOG_ERR, "can't bind udp addr");
                        exit(1);
                }
                        syslog(LOG_ERR, "can't bind udp addr");
                        exit(1);
                }
-               if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_UDP, NFS_PORT)) {
+               if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
+                   !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)) {
                        syslog(LOG_ERR, "can't register with udp portmap");
                        exit(1);
                }
                        syslog(LOG_ERR, "can't register with udp portmap");
                        exit(1);
                }
@@ -365,7 +418,8 @@ main(argc, argv, envp)
                        syslog(LOG_ERR, "listen failed");
                        exit(1);
                }
                        syslog(LOG_ERR, "listen failed");
                        exit(1);
                }
-               if (!pmap_set(RPCPROG_NFS, NFS_VER2, IPPROTO_TCP, NFS_PORT)) {
+               if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
+                   !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)) {
                        syslog(LOG_ERR, "can't register tcp with portmap");
                        exit(1);
                }
                        syslog(LOG_ERR, "can't register tcp with portmap");
                        exit(1);
                }
@@ -454,7 +508,7 @@ main(argc, argv, envp)
        if (connect_type_cnt == 0)
                exit(0);
 
        if (connect_type_cnt == 0)
                exit(0);
 
-       setproctitle("nfsd-master");
+       setproctitle("master");
 
        /*
         * Loop forever accepting connections and passing the sockets
 
        /*
         * Loop forever accepting connections and passing the sockets
@@ -528,7 +582,7 @@ main(argc, argv, envp)
 void
 usage()
 {
 void
 usage()
 {
-       (void)fprintf(stderr, "nfsd %s\n", USAGE);
+       (void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
        exit(1);
 }
 
        exit(1);
 }
 
@@ -544,7 +598,7 @@ reapchild(signo)
        int signo;
 {
 
        int signo;
 {
 
-       while (wait3(NULL, WNOHANG, NULL));
+       while (wait3(NULL, WNOHANG, NULL) > 0);
 }
 
 void
 }
 
 void
@@ -555,7 +609,7 @@ setproctitle(a)
        char buf[80];
 
        cp = Argv[0];
        char buf[80];
 
        cp = Argv[0];
-       (void)snprintf(buf, sizeof(buf), "%s", a);
+       (void)snprintf(buf, sizeof(buf), "nfsd-%s", a);
        (void)strncpy(cp, buf, LastArg - cp);
        cp += strlen(cp);
        while (cp < LastArg)
        (void)strncpy(cp, buf, LastArg - cp);
        cp += strlen(cp);
        while (cp < LastArg)
index 9bb9c5f..6853c10 100644 (file)
@@ -6,7 +6,7 @@
 .\"
 .\" %sccs.include.redist.man%
 .\"
 .\"
 .\" %sccs.include.redist.man%
 .\"
-.\"     @(#)showmount.8        8.2 (Berkeley) %G%
+.\"     @(#)showmount.8        8.3 (Berkeley) %G%
 .\"
 .Dd 
 .Dt SHOWMOUNT 8
 .\"
 .Dd 
 .Dt SHOWMOUNT 8
@@ -16,7 +16,7 @@
 .Nd show remote nfs mounts on host
 .Sh SYNOPSIS
 .Nm showmount
 .Nd show remote nfs mounts on host
 .Sh SYNOPSIS
 .Nm showmount
-.Op Fl ade
+.Op Fl ade3
 .Op Ar host
 .Sh DESCRIPTION
 .Nm Showmount
 .Op Ar host
 .Sh DESCRIPTION
 .Nm Showmount
@@ -30,7 +30,10 @@ file systems mounted
 on the host. See
 .%T "NFS: Network File System Protocol Specification" ,
 RFC 1094,
 on the host. See
 .%T "NFS: Network File System Protocol Specification" ,
 RFC 1094,
-Appendix A ,
+Appendix A,
+and
+.%T "NFS: Network File System Version 3 Protocol Specification" ,
+Appendix I,
 for a detailed description of the protocol.
 .Bl -tag -width Ds
 .It Fl a
 for a detailed description of the protocol.
 .Bl -tag -width Ds
 .It Fl a
@@ -44,6 +47,8 @@ List directory paths of mount points instead of hosts
 Show the
 .Ar host Ns 's
 exports list
 Show the
 .Ar host Ns 's
 exports list
+.It Fl 3
+Use mount protocol Version 3, compatible with NFS Version 3.
 .El
 .Sh SEE ALSO
 .Xr mount 1 ,
 .El
 .Sh SEE ALSO
 .Xr mount 1 ,
index 038ddbf..8a7c73f 100644 (file)
@@ -15,7 +15,7 @@ static char copyright[] =
 #endif not lint
 
 #ifndef lint
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)showmount.c        8.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)showmount.c        8.3 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/types.h>
 #endif not lint
 
 #include <sys/types.h>
@@ -72,6 +72,7 @@ int   xdr_exports __P((XDR *, struct exportslist **));
  * This command queries the NFS mount daemon for it's mount list and/or
  * it's exports list and prints them out.
  * See "NFS: Network File System Protocol Specification, RFC1094, Appendix A"
  * This command queries the NFS mount daemon for it's mount list and/or
  * it's exports list and prints them out.
  * See "NFS: Network File System Protocol Specification, RFC1094, Appendix A"
+ * and the "Network File System Protocol XXX.."
  * for detailed information on the protocol.
  */
 int
  * for detailed information on the protocol.
  */
 int
@@ -81,10 +82,10 @@ main(argc, argv)
 {
        struct exportslist *exp;
        struct grouplist *grp;
 {
        struct exportslist *exp;
        struct grouplist *grp;
-       int estat, rpcs = 0;
+       int estat, rpcs = 0, mntvers = 1;
        char ch, *host;
 
        char ch, *host;
 
-       while ((ch = getopt(argc, argv, "ade")) != EOF)
+       while ((ch = getopt(argc, argv, "ade3")) != EOF)
                switch((char)ch) {
                case 'a':
                        if (type == 0) {
                switch((char)ch) {
                case 'a':
                        if (type == 0) {
@@ -103,6 +104,9 @@ main(argc, argv)
                case 'e':
                        rpcs |= DOEXPORTS;
                        break;
                case 'e':
                        rpcs |= DOEXPORTS;
                        break;
+               case '3':
+                       mntvers = 3;
+                       break;
                case '?':
                default:
                        usage();
                case '?':
                default:
                        usage();
@@ -119,7 +123,7 @@ main(argc, argv)
                rpcs = DODUMP;
 
        if (rpcs & DODUMP)
                rpcs = DODUMP;
 
        if (rpcs & DODUMP)
-               if ((estat = callrpc(host, RPCPROG_MNT, RPCMNT_VER1,
+               if ((estat = callrpc(host, RPCPROG_MNT, mntvers,
                        RPCMNT_DUMP, xdr_void, (char *)0,
                        xdr_mntdump, (char *)&mntdump)) != 0) {
                        clnt_perrno(estat);
                        RPCMNT_DUMP, xdr_void, (char *)0,
                        xdr_mntdump, (char *)&mntdump)) != 0) {
                        clnt_perrno(estat);
@@ -127,7 +131,7 @@ main(argc, argv)
                        exit(1);
                }
        if (rpcs & DOEXPORTS)
                        exit(1);
                }
        if (rpcs & DOEXPORTS)
-               if ((estat = callrpc(host, RPCPROG_MNT, RPCMNT_VER1,
+               if ((estat = callrpc(host, RPCPROG_MNT, mntvers,
                        RPCMNT_EXPORT, xdr_void, (char *)0,
                        xdr_exports, (char *)&exports)) != 0) {
                        clnt_perrno(estat);
                        RPCMNT_EXPORT, xdr_void, (char *)0,
                        xdr_exports, (char *)&exports)) != 0) {
                        clnt_perrno(estat);