forked from pool/util-linux
629 lines
16 KiB
Diff
629 lines
16 KiB
Diff
--- util-linux-2.12q/mount/Makefile
|
|
+++ util-linux-2.12q/mount/Makefile
|
|
@@ -29,7 +29,7 @@
|
|
|
|
MAYBE = pivot_root swapoff
|
|
|
|
-NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
|
|
+NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o nfs4mount.o
|
|
GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
|
|
|
|
all: $(PROGS)
|
|
--- util-linux-2.12q/mount/mount.c
|
|
+++ util-linux-2.12q/mount/mount.c
|
|
@@ -847,8 +847,23 @@
|
|
"without support for the type `nfs'"));
|
|
#endif
|
|
}
|
|
+#ifdef HAVE_NFS
|
|
+ /*
|
|
+ * NFSv4 support
|
|
+ */
|
|
+ if (!fake && types && streq (types, "nfs4")) {
|
|
+ mnt_err = nfs4mount(spec, node, &flags, &extra_opts, &mount_opts, bg);
|
|
+ if (mnt_err)
|
|
+ return mnt_err;
|
|
+ goto nosigblock;
|
|
+#else
|
|
+ die (EX_SOFTWARE, _("mount: this version was compiled "
|
|
+ "without support for the type `nfs4'"));
|
|
+#endif
|
|
+ }
|
|
|
|
block_signals (SIG_BLOCK);
|
|
+nosigblock:
|
|
|
|
if (!fake) {
|
|
mnt5_res = guess_fstype_and_mount (spec, node, &types, flags & ~MS_NOSYS,
|
|
--- util-linux-2.12q/mount/nfs4mount.c
|
|
+++ util-linux-2.12q/mount/nfs4mount.c
|
|
@@ -0,0 +1,460 @@
|
|
+/*
|
|
+ * nfs4mount.c -- Linux NFS mount
|
|
+ * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * Note: this file based on the original nfsmount.c
|
|
+ */
|
|
+
|
|
+#include "../defines.h" /* for HAVE_rpcsvc_nfs_prot_h and HAVE_inet_aton */
|
|
+
|
|
+#include <linux/posix_types.h>
|
|
+#include <asm/posix_types.h>
|
|
+#undef __FD_CLR
|
|
+#undef __FD_SET
|
|
+#undef __FD_ISSET
|
|
+#undef __FD_ZERO
|
|
+
|
|
+#include <unistd.h>
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+#include <errno.h>
|
|
+#include <netdb.h>
|
|
+#include <time.h>
|
|
+#include <sys/socket.h>
|
|
+#include <sys/time.h>
|
|
+#include <sys/utsname.h>
|
|
+#include <sys/stat.h>
|
|
+#include <netinet/in.h>
|
|
+#include <arpa/inet.h>
|
|
+#include <rpc/auth.h>
|
|
+#ifdef HAVE_rpcsvc_nfs_prot_h
|
|
+#include <rpcsvc/nfs_prot.h>
|
|
+#else
|
|
+#include <linux/nfs.h>
|
|
+#define nfsstat nfs_stat
|
|
+#endif
|
|
+
|
|
+#include "sundries.h"
|
|
+
|
|
+#include "mount_constants.h"
|
|
+#include "nfs4_mount.h"
|
|
+
|
|
+#include "nls.h"
|
|
+
|
|
+#ifndef NFS_PORT
|
|
+#define NFS_PORT 2049
|
|
+#endif
|
|
+
|
|
+extern int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int);
|
|
+extern void rpc_strerror(void);
|
|
+
|
|
+struct {
|
|
+ char *flavour;
|
|
+ int fnum;
|
|
+} flav_map[] = {
|
|
+ { "krb5", RPC_AUTH_GSS_KRB5 },
|
|
+ { "krb5i", RPC_AUTH_GSS_KRB5I },
|
|
+ { "krb5p", RPC_AUTH_GSS_KRB5P },
|
|
+ { "lipkey", RPC_AUTH_GSS_LKEY },
|
|
+ { "lipkey-i", RPC_AUTH_GSS_LKEYI },
|
|
+ { "lipkey-p", RPC_AUTH_GSS_LKEYP },
|
|
+ { "spkm3", RPC_AUTH_GSS_SPKM },
|
|
+ { "spkm3i", RPC_AUTH_GSS_SPKMI },
|
|
+ { "spkm3p", RPC_AUTH_GSS_SPKMP },
|
|
+ { "unix", AUTH_UNIX },
|
|
+ { "sys", AUTH_SYS },
|
|
+ { "null", AUTH_NULL },
|
|
+ { "none", AUTH_NONE },
|
|
+};
|
|
+
|
|
+#define FMAPSIZE (sizeof(flav_map)/sizeof(flav_map[0]))
|
|
+#define MAX_USER_FLAVOUR 16
|
|
+
|
|
+static int parse_sec(char *sec, int *pseudoflavour)
|
|
+{
|
|
+ int i, num_flavour = 0;
|
|
+
|
|
+ for (sec = strtok(sec, ":"); sec; sec = strtok(NULL, ":")) {
|
|
+ if (num_flavour >= MAX_USER_FLAVOUR) {
|
|
+ fprintf(stderr,
|
|
+ _("mount: maximum number of security flavors "
|
|
+ "exceeded\n"));
|
|
+ return 0;
|
|
+ }
|
|
+ for (i = 0; i < FMAPSIZE; i++) {
|
|
+ if (strcmp(sec, flav_map[i].flavour) == 0) {
|
|
+ pseudoflavour[num_flavour++] = flav_map[i].fnum;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (i == FMAPSIZE) {
|
|
+ fprintf(stderr,
|
|
+ _("mount: unknown security type %s\n"), sec);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ if (!num_flavour)
|
|
+ fprintf(stderr,
|
|
+ _("mount: no security flavors passed to sec= option\n"));
|
|
+ return num_flavour;
|
|
+}
|
|
+
|
|
+static int parse_devname(char *hostdir, char **hostname, char **dirname)
|
|
+{
|
|
+ char *s;
|
|
+
|
|
+ if (!(s = strchr(hostdir, ':'))) {
|
|
+ fprintf(stderr,
|
|
+ _("mount: "
|
|
+ "directory to mount not in host:dir format\n"));
|
|
+ return -1;
|
|
+ }
|
|
+ *hostname = hostdir;
|
|
+ *dirname = s + 1;
|
|
+ *s = '\0';
|
|
+ /* Ignore all but first hostname in replicated mounts
|
|
+ until they can be fully supported. (mack@sgi.com) */
|
|
+ if ((s = strchr(hostdir, ','))) {
|
|
+ *s = '\0';
|
|
+ fprintf(stderr,
|
|
+ _("mount: warning: "
|
|
+ "multiple hostnames not supported\n"));
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr)
|
|
+{
|
|
+ struct hostent *hp;
|
|
+ addr->sin_family = AF_INET;
|
|
+
|
|
+ if (inet_aton(hostname, &addr->sin_addr))
|
|
+ return 0;
|
|
+ if ((hp = gethostbyname(hostname)) == NULL) {
|
|
+ fprintf(stderr, _("mount: can't get address for %s\n"),
|
|
+ hostname);
|
|
+ return -1;
|
|
+ }
|
|
+ if (hp->h_length > sizeof(struct in_addr)) {
|
|
+ fprintf(stderr,
|
|
+ _("mount: got bad hp->h_length\n"));
|
|
+ hp->h_length = sizeof(struct in_addr);
|
|
+ }
|
|
+ memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int get_my_ipv4addr(char *ip_addr, int len)
|
|
+{
|
|
+ char myname[1024];
|
|
+ struct sockaddr_in myaddr;
|
|
+
|
|
+ if (gethostname(myname, sizeof(myname))) {
|
|
+ fprintf(stderr, _("mount: can't determine client address\n"));
|
|
+ return -1;
|
|
+ }
|
|
+ if (fill_ipv4_sockaddr(myname, &myaddr))
|
|
+ return -1;
|
|
+ snprintf(ip_addr, len, "%s", inet_ntoa(myaddr.sin_addr));
|
|
+ ip_addr[len-1] = '\0';
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* Convert RPC errors into strings */
|
|
+void rpc_strerror(void)
|
|
+{
|
|
+ int cf_stat = rpc_createerr.cf_stat;
|
|
+ int cf_errno = rpc_createerr.cf_error.re_errno;
|
|
+ char *ptr, *estr = clnt_sperrno(cf_stat);
|
|
+
|
|
+ if (estr) {
|
|
+ if ((ptr = index(estr, ':')))
|
|
+ estr = ++ptr;
|
|
+
|
|
+ fprintf(stderr, "RPC Error: %d (%s )\n", cf_stat, estr);
|
|
+ if (cf_stat == RPC_SYSTEMERROR)
|
|
+ fprintf(stderr, "System Error: %d (%s)\n", cf_errno, strerror(cf_errno));
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
+clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,
|
|
+ const u_int prot)
|
|
+{
|
|
+ static const struct timeval TIMEOUT = { 20, 0 };
|
|
+ static const struct timeval RETRY_TIMEOUT = { 3, 0 };
|
|
+ CLIENT *clnt=NULL;
|
|
+ int sock, stat;
|
|
+ static char clnt_res;
|
|
+
|
|
+ rpc_createerr.cf_stat = stat = 0;
|
|
+ sock = RPC_ANYSOCK;
|
|
+ switch(prot) {
|
|
+ case IPPROTO_UDP:
|
|
+ clnt = clntudp_bufcreate(saddr, prog, vers,
|
|
+ RETRY_TIMEOUT, &sock,
|
|
+ RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
|
|
+ break;
|
|
+ case IPPROTO_TCP:
|
|
+ clnt = clnttcp_create(saddr, prog, vers, &sock,
|
|
+ RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
|
|
+ break;
|
|
+ default:
|
|
+ goto out_bad;
|
|
+ }
|
|
+ if (!clnt)
|
|
+ goto out_bad;
|
|
+ memset(&clnt_res, 0, sizeof(clnt_res));
|
|
+ stat = clnt_call(clnt, NULLPROC,
|
|
+ (xdrproc_t)xdr_void, (caddr_t)NULL,
|
|
+ (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
|
|
+ TIMEOUT);
|
|
+ clnt_destroy(clnt);
|
|
+ close(sock);
|
|
+ if (stat != RPC_PROGVERSMISMATCH)
|
|
+ return 1;
|
|
+
|
|
+ out_bad:
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int nfs4mount(const char *spec, const char *node, int *flags,
|
|
+ char **extra_opts, char **mount_opts,
|
|
+ int running_bg)
|
|
+{
|
|
+ static struct nfs4_mount_data data;
|
|
+ static char hostdir[1024];
|
|
+ static char ip_addr[16] = "127.0.0.1";
|
|
+ static struct sockaddr_in server_addr;
|
|
+ static int pseudoflavour[MAX_USER_FLAVOUR];
|
|
+ int num_flavour = 0;
|
|
+
|
|
+ char *hostname, *dirname, *old_opts;
|
|
+ char new_opts[1024];
|
|
+ char *opt, *opteq;
|
|
+ char *s;
|
|
+ int val;
|
|
+ int bg, soft, intr;
|
|
+ int nocto, noac;
|
|
+ int retry;
|
|
+ int retval;
|
|
+
|
|
+ retval = EX_FAIL;
|
|
+ if (strlen(spec) >= sizeof(hostdir)) {
|
|
+ fprintf(stderr, _("mount: "
|
|
+ "excessively long host:dir argument\n"));
|
|
+ goto fail;
|
|
+ }
|
|
+ strcpy(hostdir, spec);
|
|
+ if (parse_devname(hostdir, &hostname, &dirname))
|
|
+ goto fail;
|
|
+
|
|
+ if (fill_ipv4_sockaddr(hostname, &server_addr))
|
|
+ goto fail;
|
|
+ if (get_my_ipv4addr(ip_addr, sizeof(ip_addr)))
|
|
+ goto fail;
|
|
+
|
|
+ /* add IP address to mtab options for use when unmounting */
|
|
+ s = inet_ntoa(server_addr.sin_addr);
|
|
+ old_opts = *extra_opts;
|
|
+ if (!old_opts)
|
|
+ old_opts = "";
|
|
+ if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
|
|
+ fprintf(stderr, _("mount: "
|
|
+ "excessively long option argument\n"));
|
|
+ goto fail;
|
|
+ }
|
|
+ snprintf(new_opts, sizeof(new_opts), "%s%saddr=%s",
|
|
+ old_opts, *old_opts ? "," : "", s);
|
|
+ *extra_opts = xstrdup(new_opts);
|
|
+
|
|
+ /* Set default options.
|
|
+ * rsize/wsize and timeo are left 0 in order to
|
|
+ * let the kernel decide.
|
|
+ */
|
|
+ memset(&data, 0, sizeof(data));
|
|
+ data.retrans = 3;
|
|
+ data.acregmin = 3;
|
|
+ data.acregmax = 60;
|
|
+ data.acdirmin = 30;
|
|
+ data.acdirmax = 60;
|
|
+ data.proto = IPPROTO_TCP;
|
|
+
|
|
+ bg = 0;
|
|
+ soft = 0;
|
|
+ intr = NFS4_MOUNT_INTR;
|
|
+ nocto = 0;
|
|
+ noac = 0;
|
|
+ retry = 10000; /* 10000 minutes ~ 1 week */
|
|
+
|
|
+ /*
|
|
+ * NFSv4 specifies that the default port should be 2049
|
|
+ */
|
|
+ server_addr.sin_port = htons(NFS_PORT);
|
|
+
|
|
+ /* parse options */
|
|
+
|
|
+ for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
|
|
+ if ((opteq = strchr(opt, '='))) {
|
|
+ val = atoi(opteq + 1);
|
|
+ *opteq = '\0';
|
|
+ if (!strcmp(opt, "rsize"))
|
|
+ data.rsize = val;
|
|
+ else if (!strcmp(opt, "wsize"))
|
|
+ data.wsize = val;
|
|
+ else if (!strcmp(opt, "timeo"))
|
|
+ data.timeo = val;
|
|
+ else if (!strcmp(opt, "retrans"))
|
|
+ data.retrans = val;
|
|
+ else if (!strcmp(opt, "acregmin"))
|
|
+ data.acregmin = val;
|
|
+ else if (!strcmp(opt, "acregmax"))
|
|
+ data.acregmax = val;
|
|
+ else if (!strcmp(opt, "acdirmin"))
|
|
+ data.acdirmin = val;
|
|
+ else if (!strcmp(opt, "acdirmax"))
|
|
+ data.acdirmax = val;
|
|
+ else if (!strcmp(opt, "actimeo")) {
|
|
+ data.acregmin = val;
|
|
+ data.acregmax = val;
|
|
+ data.acdirmin = val;
|
|
+ data.acdirmax = val;
|
|
+ }
|
|
+ else if (!strcmp(opt, "retry"))
|
|
+ retry = val;
|
|
+ else if (!strcmp(opt, "port"))
|
|
+ server_addr.sin_port = htons(val);
|
|
+ else if (!strcmp(opt, "proto")) {
|
|
+ if (!strncmp(opteq+1, "tcp", 3))
|
|
+ data.proto = IPPROTO_TCP;
|
|
+ else if (!strncmp(opteq+1, "udp", 3))
|
|
+ data.proto = IPPROTO_UDP;
|
|
+ else
|
|
+ printf(_("Warning: Unrecognized proto= option.\n"));
|
|
+ } else if (!strcmp(opt, "clientaddr")) {
|
|
+ if (strlen(opteq+1) >= sizeof(ip_addr))
|
|
+ printf(_("Invalid client address %s"),
|
|
+ opteq+1);
|
|
+ strncpy(ip_addr,opteq+1, sizeof(ip_addr));
|
|
+ ip_addr[sizeof(ip_addr)-1] = '\0';
|
|
+ } else if (!strcmp(opt, "sec")) {
|
|
+ num_flavour = parse_sec(opteq+1, pseudoflavour);
|
|
+ if (!num_flavour)
|
|
+ goto fail;
|
|
+ } else if (!strcmp(opt, "addr")) {
|
|
+ /* ignore */;
|
|
+ } else {
|
|
+ printf(_("unknown nfs mount parameter: "
|
|
+ "%s=%d\n"), opt, val);
|
|
+ goto fail;
|
|
+ }
|
|
+ } else {
|
|
+ val = 1;
|
|
+ if (!strncmp(opt, "no", 2)) {
|
|
+ val = 0;
|
|
+ opt += 2;
|
|
+ }
|
|
+ if (!strcmp(opt, "bg"))
|
|
+ bg = val;
|
|
+ else if (!strcmp(opt, "fg"))
|
|
+ bg = !val;
|
|
+ else if (!strcmp(opt, "soft"))
|
|
+ soft = val;
|
|
+ else if (!strcmp(opt, "hard"))
|
|
+ soft = !val;
|
|
+ else if (!strcmp(opt, "intr"))
|
|
+ intr = val;
|
|
+ else if (!strcmp(opt, "cto"))
|
|
+ nocto = !val;
|
|
+ else if (!strcmp(opt, "ac"))
|
|
+ noac = !val;
|
|
+ else {
|
|
+ if (!sloppy) {
|
|
+ printf(_("unknown nfs mount option: "
|
|
+ "%s%s\n"), val ? "" : "no", opt);
|
|
+ goto fail;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ data.flags = (soft ? NFS4_MOUNT_SOFT : 0)
|
|
+ | (intr ? NFS4_MOUNT_INTR : 0)
|
|
+ | (nocto ? NFS4_MOUNT_NOCTO : 0)
|
|
+ | (noac ? NFS4_MOUNT_NOAC : 0);
|
|
+
|
|
+ if (num_flavour == 0)
|
|
+ pseudoflavour[num_flavour++] = AUTH_UNIX;
|
|
+ data.auth_flavourlen = num_flavour;
|
|
+ data.auth_flavours = pseudoflavour;
|
|
+
|
|
+ data.client_addr.data = ip_addr;
|
|
+ data.client_addr.len = strlen(ip_addr);
|
|
+
|
|
+ data.mnt_path.data = dirname;
|
|
+ data.mnt_path.len = strlen(dirname);
|
|
+
|
|
+ data.hostname.data = hostname;
|
|
+ data.hostname.len = strlen(hostname);
|
|
+ data.host_addr = (struct sockaddr *)&server_addr;
|
|
+ data.host_addrlen = sizeof(server_addr);
|
|
+
|
|
+#ifdef NFS_MOUNT_DEBUG
|
|
+ printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
|
|
+ data.rsize, data.wsize, data.timeo, data.retrans);
|
|
+ printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
|
|
+ data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
|
|
+ printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
|
|
+ ntohs(server_addr.sin_port), bg, retry, data.flags);
|
|
+ printf("soft = %d, intr = %d, nocto = %d, noac = %d\n",
|
|
+ (data.flags & NFS4_MOUNT_SOFT) != 0,
|
|
+ (data.flags & NFS4_MOUNT_INTR) != 0,
|
|
+ (data.flags & NFS4_MOUNT_NOCTO) != 0,
|
|
+ (data.flags & NFS4_MOUNT_NOAC) != 0);
|
|
+
|
|
+ if (num_flavour > 0) {
|
|
+ int pf_cnt, i;
|
|
+
|
|
+ printf("sec = ");
|
|
+ for (pf_cnt = 0; pf_cnt < num_flavour; pf_cnt++) {
|
|
+ for (i = 0; i < FMAPSIZE; i++) {
|
|
+ if (flav_map[i].fnum == pseudoflavour[pf_cnt]) {
|
|
+ printf("%s", flav_map[i].flavour);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ printf("%s", (pf_cnt < num_flavour-1) ? ":" : "\n");
|
|
+ }
|
|
+ }
|
|
+ printf("proto = %s\n", (data.proto == IPPROTO_TCP) ? "tcp" : "udp");
|
|
+#endif
|
|
+
|
|
+ data.version = NFS4_MOUNT_VERSION;
|
|
+
|
|
+ clnt_ping(&server_addr, NFS_PROGRAM, 4, data.proto);
|
|
+ if (rpc_createerr.cf_stat) {
|
|
+ fprintf(stderr, "mount to NFS server '%s' failed.\n", data.hostname.data);
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ *mount_opts = (char *) &data;
|
|
+ /* clean up */
|
|
+ return 0;
|
|
+
|
|
+fail:
|
|
+ if (verbose) {
|
|
+ rpc_strerror();
|
|
+ }
|
|
+ return retval;
|
|
+}
|
|
--- util-linux-2.12q/mount/nfs4_mount.h
|
|
+++ util-linux-2.12q/mount/nfs4_mount.h
|
|
@@ -0,0 +1,82 @@
|
|
+#ifndef _LINUX_NFS4_MOUNT_H
|
|
+#define _LINUX_NFS4_MOUNT_H
|
|
+
|
|
+/*
|
|
+ * linux/include/linux/nfs4_mount.h
|
|
+ *
|
|
+ * Copyright (C) 2002 Trond Myklebust
|
|
+ *
|
|
+ * structure passed from user-space to kernel-space during an nfsv4 mount
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * WARNING! Do not delete or change the order of these fields. If
|
|
+ * a new field is required then add it to the end. The version field
|
|
+ * tracks which fields are present. This will ensure some measure of
|
|
+ * mount-to-kernel version compatibility. Some of these aren't used yet
|
|
+ * but here they are anyway.
|
|
+ */
|
|
+#define NFS4_MOUNT_VERSION 1
|
|
+
|
|
+struct nfs_string {
|
|
+ unsigned int len;
|
|
+ const char* data;
|
|
+};
|
|
+
|
|
+struct nfs4_mount_data {
|
|
+ int version; /* 1 */
|
|
+ int flags; /* 1 */
|
|
+ int rsize; /* 1 */
|
|
+ int wsize; /* 1 */
|
|
+ int timeo; /* 1 */
|
|
+ int retrans; /* 1 */
|
|
+ int acregmin; /* 1 */
|
|
+ int acregmax; /* 1 */
|
|
+ int acdirmin; /* 1 */
|
|
+ int acdirmax; /* 1 */
|
|
+
|
|
+ /* see the definition of 'struct clientaddr4' in RFC3010 */
|
|
+ struct nfs_string client_addr; /* 1 */
|
|
+
|
|
+ /* Mount path */
|
|
+ struct nfs_string mnt_path; /* 1 */
|
|
+
|
|
+ /* Server details */
|
|
+ struct nfs_string hostname; /* 1 */
|
|
+ /* Server IP address */
|
|
+ unsigned int host_addrlen; /* 1 */
|
|
+ struct sockaddr* host_addr; /* 1 */
|
|
+
|
|
+ /* Transport protocol to use */
|
|
+ int proto; /* 1 */
|
|
+
|
|
+ /* Pseudo-flavours to use for authentication. See RFC2623 */
|
|
+ int auth_flavourlen; /* 1 */
|
|
+ int *auth_flavours; /* 1 */
|
|
+};
|
|
+
|
|
+/* bits in the flags field */
|
|
+/* Note: the fields that correspond to existing NFSv2/v3 mount options
|
|
+ * should mirror the values from include/linux/nfs_mount.h
|
|
+ */
|
|
+
|
|
+#define NFS4_MOUNT_SOFT 0x0001 /* 1 */
|
|
+#define NFS4_MOUNT_INTR 0x0002 /* 1 */
|
|
+#define NFS4_MOUNT_NOCTO 0x0010 /* 1 */
|
|
+#define NFS4_MOUNT_NOAC 0x0020 /* 1 */
|
|
+#define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */
|
|
+#define NFS4_MOUNT_FLAGMASK 0xFFFF
|
|
+
|
|
+/* pseudoflavors: */
|
|
+
|
|
+#define RPC_AUTH_GSS_KRB5 390003
|
|
+#define RPC_AUTH_GSS_KRB5I 390004
|
|
+#define RPC_AUTH_GSS_KRB5P 390005
|
|
+#define RPC_AUTH_GSS_LKEY 390006
|
|
+#define RPC_AUTH_GSS_LKEYI 390007
|
|
+#define RPC_AUTH_GSS_LKEYP 390008
|
|
+#define RPC_AUTH_GSS_SPKM 390009
|
|
+#define RPC_AUTH_GSS_SPKMI 390010
|
|
+#define RPC_AUTH_GSS_SPKMP 390011
|
|
+
|
|
+#endif
|
|
--- util-linux-2.12q/mount/nfs_mount4.h
|
|
+++ util-linux-2.12q/mount/nfs_mount4.h
|
|
@@ -8,7 +8,9 @@
|
|
* so it is easiest to ignore the kernel altogether (at compile time).
|
|
*/
|
|
|
|
-#define NFS_MOUNT_VERSION 4
|
|
+#define NFS_MOUNT_VERSION 6
|
|
+#define NFS_MAX_CONTEXT_LEN 256
|
|
+
|
|
|
|
struct nfs2_fh {
|
|
char data[32];
|
|
@@ -36,6 +38,9 @@
|
|
int namlen; /* 2 */
|
|
unsigned int bsize; /* 3 */
|
|
struct nfs3_fh root; /* 4 */
|
|
+ int pseudoflavor; /* 5 */
|
|
+ char context[NFS_MAX_CONTEXT_LEN + 1]; /* 6 */
|
|
+
|
|
};
|
|
|
|
/* bits in the flags field */
|
|
@@ -52,3 +57,19 @@
|
|
#define NFS_MOUNT_NONLM 0x0200 /* 3 */
|
|
#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */
|
|
#define NFS_MOUNT_NOACL 0x0800 /* 4 */
|
|
+#define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
|
|
+
|
|
+/* security pseudoflavors */
|
|
+
|
|
+#ifndef AUTH_GSS_KRB5
|
|
+#define AUTH_GSS_KRB5 390003
|
|
+#define AUTH_GSS_KRB5I 390004
|
|
+#define AUTH_GSS_KRB5P 390005
|
|
+#define AUTH_GSS_LKEY 390006
|
|
+#define AUTH_GSS_LKEYI 390007
|
|
+#define AUTH_GSS_LKEYP 390008
|
|
+#define AUTH_GSS_SPKM 390009
|
|
+#define AUTH_GSS_SPKMI 390010
|
|
+#define AUTH_GSS_SPKMP 390011
|
|
+#endif
|
|
+
|