- Updated to the latest pseudo root release (rel9).
This commit is contained in:
parent
267c347dc8
commit
c2754f092e
@ -1,717 +0,0 @@
|
|||||||
diff -up nfs-utils-1.2.1/support/export/xtab.c.orig nfs-utils-1.2.1/support/export/xtab.c
|
|
||||||
--- nfs-utils-1.2.1/support/export/xtab.c.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/support/export/xtab.c 2009-11-11 14:01:56.370963000 -0500
|
|
||||||
@@ -19,7 +19,9 @@
|
|
||||||
#include "exportfs.h"
|
|
||||||
#include "xio.h"
|
|
||||||
#include "xlog.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
|
|
||||||
+int v4root_needed;
|
|
||||||
static void cond_rename(char *newfile, char *oldfile);
|
|
||||||
|
|
||||||
static int
|
|
||||||
@@ -36,6 +38,8 @@ xtab_read(char *xtab, char *lockfn, int
|
|
||||||
if ((lockid = xflock(lockfn, "r")) < 0)
|
|
||||||
return 0;
|
|
||||||
setexportent(xtab, "r");
|
|
||||||
+ if (is_export == 1)
|
|
||||||
+ v4root_needed = 1;
|
|
||||||
while ((xp = getexportent(is_export==0, 0)) != NULL) {
|
|
||||||
if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
|
|
||||||
!(exp = export_create(xp, is_export!=1))) {
|
|
||||||
@@ -48,6 +52,8 @@ xtab_read(char *xtab, char *lockfn, int
|
|
||||||
case 1:
|
|
||||||
exp->m_xtabent = 1;
|
|
||||||
exp->m_mayexport = 1;
|
|
||||||
+ if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
|
|
||||||
+ v4root_needed = 0;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
exp->m_exported = -1;/* may be exported */
|
|
||||||
diff -up nfs-utils-1.2.1/support/include/exportfs.h.orig nfs-utils-1.2.1/support/include/exportfs.h
|
|
||||||
--- nfs-utils-1.2.1/support/include/exportfs.h.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/support/include/exportfs.h 2009-11-11 14:01:56.377960000 -0500
|
|
||||||
@@ -12,6 +12,17 @@
|
|
||||||
#include <netdb.h>
|
|
||||||
#include "nfslib.h"
|
|
||||||
|
|
||||||
+enum nfsd_fsid {
|
|
||||||
+ FSID_DEV = 0,
|
|
||||||
+ FSID_NUM,
|
|
||||||
+ FSID_MAJOR_MINOR,
|
|
||||||
+ FSID_ENCODE_DEV,
|
|
||||||
+ FSID_UUID4_INUM,
|
|
||||||
+ FSID_UUID8,
|
|
||||||
+ FSID_UUID16,
|
|
||||||
+ FSID_UUID16_INUM,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
enum {
|
|
||||||
MCL_FQDN = 0,
|
|
||||||
MCL_SUBNETWORK,
|
|
||||||
diff -up nfs-utils-1.2.1/support/include/nfs/export.h.orig nfs-utils-1.2.1/support/include/nfs/export.h
|
|
||||||
--- nfs-utils-1.2.1/support/include/nfs/export.h.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/support/include/nfs/export.h 2009-11-11 14:01:56.383967000 -0500
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#define NFSEXP_FSID 0x2000
|
|
||||||
#define NFSEXP_CROSSMOUNT 0x4000
|
|
||||||
#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
|
|
||||||
-#define NFSEXP_ALLFLAGS 0xFFFF
|
|
||||||
+#define NFSEXP_V4ROOT 0x10000
|
|
||||||
+#define NFSEXP_ALLFLAGS 0x1FFFF
|
|
||||||
|
|
||||||
#endif /* _NSF_EXPORT_H */
|
|
||||||
diff -up nfs-utils-1.2.1/support/include/nfslib.h.orig nfs-utils-1.2.1/support/include/nfslib.h
|
|
||||||
--- nfs-utils-1.2.1/support/include/nfslib.h.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/support/include/nfslib.h 2009-11-11 14:01:56.390963000 -0500
|
|
||||||
@@ -88,6 +88,7 @@ struct exportent {
|
|
||||||
int e_fslocmethod;
|
|
||||||
char * e_fslocdata;
|
|
||||||
char * e_uuid;
|
|
||||||
+ void * e_v4root;
|
|
||||||
struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
diff -up /dev/null nfs-utils-1.2.1/support/include/v4root.h
|
|
||||||
--- /dev/null 2009-11-11 11:00:17.075766506 -0500
|
|
||||||
+++ nfs-utils-1.2.1/support/include/v4root.h 2009-11-11 14:01:56.399965000 -0500
|
|
||||||
@@ -0,0 +1,20 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2009 Red Hat <nfs@redhat.com>
|
|
||||||
+ * support/include/v4root.h
|
|
||||||
+ *
|
|
||||||
+ * Support routines for dynamic pseudo roots.
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef V4ROOT_H
|
|
||||||
+#define V4ROOT_H
|
|
||||||
+
|
|
||||||
+extern int v4root_needed;
|
|
||||||
+
|
|
||||||
+extern struct exportent *v4root_chkroot(int , unsigned int , char *);
|
|
||||||
+extern struct exportent *v4root_export(char *, int);
|
|
||||||
+extern struct exportent *v4root_lookup(char *, nfs_export *);
|
|
||||||
+extern void v4root_free(struct exportent *);
|
|
||||||
+extern void v4root_unset(void), v4root_set(void);
|
|
||||||
+
|
|
||||||
+#endif /* V4ROOT_H */
|
|
||||||
diff -up nfs-utils-1.2.1/utils/mountd/auth.c.orig nfs-utils-1.2.1/utils/mountd/auth.c
|
|
||||||
--- nfs-utils-1.2.1/utils/mountd/auth.c.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/utils/mountd/auth.c 2009-11-11 14:01:56.405963000 -0500
|
|
||||||
@@ -20,6 +20,7 @@
|
|
||||||
#include "exportfs.h"
|
|
||||||
#include "mountd.h"
|
|
||||||
#include "xmalloc.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
|
|
||||||
enum auth_error
|
|
||||||
{
|
|
||||||
@@ -98,10 +99,13 @@ auth_reload()
|
|
||||||
last_inode = stb.st_ino;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ v4root_unset();
|
|
||||||
export_freeall();
|
|
||||||
memset(&my_client, 0, sizeof(my_client));
|
|
||||||
xtab_export_read();
|
|
||||||
check_useipaddr();
|
|
||||||
+ v4root_set();
|
|
||||||
+
|
|
||||||
++counter;
|
|
||||||
|
|
||||||
return counter;
|
|
||||||
diff -up nfs-utils-1.2.1/utils/mountd/cache.c.orig nfs-utils-1.2.1/utils/mountd/cache.c
|
|
||||||
--- nfs-utils-1.2.1/utils/mountd/cache.c.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/utils/mountd/cache.c 2009-11-11 14:01:56.414960000 -0500
|
|
||||||
@@ -32,23 +32,12 @@
|
|
||||||
#include "xmalloc.h"
|
|
||||||
#include "fsloc.h"
|
|
||||||
#include "pseudoflavors.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
|
|
||||||
#ifdef USE_BLKID
|
|
||||||
#include "blkid/blkid.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-
|
|
||||||
-enum nfsd_fsid {
|
|
||||||
- FSID_DEV = 0,
|
|
||||||
- FSID_NUM,
|
|
||||||
- FSID_MAJOR_MINOR,
|
|
||||||
- FSID_ENCODE_DEV,
|
|
||||||
- FSID_UUID4_INUM,
|
|
||||||
- FSID_UUID8,
|
|
||||||
- FSID_UUID16,
|
|
||||||
- FSID_UUID16_INUM,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Support routines for text-based upcalls.
|
|
||||||
* Fields are separated by spaces.
|
|
||||||
@@ -135,6 +124,8 @@ void auth_unix_gid(FILE *f)
|
|
||||||
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
+ xlog(D_CALL, "auth_unix_gid: '%s'", lbuf);
|
|
||||||
+
|
|
||||||
cp = lbuf;
|
|
||||||
if (qword_get_int(&cp, &uid) != 0)
|
|
||||||
return;
|
|
||||||
@@ -391,6 +382,12 @@ void nfsd_fh(FILE *f)
|
|
||||||
|
|
||||||
auth_reload();
|
|
||||||
|
|
||||||
+ /* Check to see if the kenel is looking for the pseudo root */
|
|
||||||
+ if ((found = v4root_chkroot(fsidtype, fsidnum, fhuuid))) {
|
|
||||||
+ found_path = strdup(found->e_path);
|
|
||||||
+ goto found;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Now determine export point for this fsid/domain */
|
|
||||||
for (i=0 ; i < MCL_MAXTYPES; i++) {
|
|
||||||
nfs_export *next_exp;
|
|
||||||
@@ -511,7 +508,23 @@ void nfsd_fh(FILE *f)
|
|
||||||
*/
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
+ if (!found) {
|
|
||||||
+ /*
|
|
||||||
+ * See if this is a pesudo export
|
|
||||||
+ */
|
|
||||||
+ switch(fsidtype) {
|
|
||||||
+ case FSID_UUID4_INUM:
|
|
||||||
+ case FSID_UUID8:
|
|
||||||
+ case FSID_UUID16:
|
|
||||||
+ case FSID_UUID16_INUM:
|
|
||||||
+ found = v4root_export(fhuuid, uuidlen);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ if (found)
|
|
||||||
+ found_path = strdup(found->e_path);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
+found:
|
|
||||||
if (found)
|
|
||||||
if (cache_export_ent(dom, found, found_path) < 0)
|
|
||||||
found = 0;
|
|
||||||
@@ -629,6 +642,7 @@ void nfsd_export(FILE *f)
|
|
||||||
int found_type = 0;
|
|
||||||
struct in_addr addr;
|
|
||||||
struct hostent *he = NULL;
|
|
||||||
+ struct exportent *v4root = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
|
|
||||||
@@ -663,10 +677,18 @@ void nfsd_export(FILE *f)
|
|
||||||
path[l] == '/' &&
|
|
||||||
is_mountpoint(path)))
|
|
||||||
/* ok */;
|
|
||||||
- else
|
|
||||||
+ else {
|
|
||||||
+ /* See if the path is part of the psuedo root */
|
|
||||||
+ if (v4root_needed && !v4root)
|
|
||||||
+ v4root = v4root_lookup(path, exp);
|
|
||||||
continue;
|
|
||||||
- } else if (strcmp(path, exp->m_export.e_path) != 0)
|
|
||||||
+ }
|
|
||||||
+ } else if (strcmp(path, exp->m_export.e_path) != 0) {
|
|
||||||
+ /* See if the path is part of the psuedo root */
|
|
||||||
+ if (v4root_needed && !v4root)
|
|
||||||
+ v4root = v4root_lookup(path, exp);
|
|
||||||
continue;
|
|
||||||
+ }
|
|
||||||
if (use_ipaddr) {
|
|
||||||
if (he == NULL) {
|
|
||||||
if (!inet_aton(dom, &addr))
|
|
||||||
@@ -705,17 +727,28 @@ void nfsd_export(FILE *f)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
+ xlog(D_CALL, "nfsd_export: found: path %s", path);
|
|
||||||
if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
|
|
||||||
xlog(L_WARNING,
|
|
||||||
"Cannot export %s, possibly unsupported filesystem"
|
|
||||||
" or fsid= required", path);
|
|
||||||
dump_to_cache(f, dom, path, NULL);
|
|
||||||
}
|
|
||||||
- } else {
|
|
||||||
+ } else if (v4root) {
|
|
||||||
+ xlog(D_CALL, "nfsd_export: vroot: path %s", path);
|
|
||||||
+ dump_to_cache(f, dom, path, v4root);
|
|
||||||
+ found = (nfs_export *)v4root;
|
|
||||||
+ } else {
|
|
||||||
dump_to_cache(f, dom, path, NULL);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
- xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
|
|
||||||
+ /*
|
|
||||||
+ * If a psuedo export was create and its not needed
|
|
||||||
+ * free it up.
|
|
||||||
+ */
|
|
||||||
+ if (v4root && found != (nfs_export *)v4root)
|
|
||||||
+ v4root_free(v4root);
|
|
||||||
+
|
|
||||||
if (dom) free(dom);
|
|
||||||
if (path) free(path);
|
|
||||||
if (he) free(he);
|
|
||||||
@@ -743,7 +776,9 @@ void cache_open(void)
|
|
||||||
if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
|
|
||||||
continue;
|
|
||||||
sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name);
|
|
||||||
- cachelist[i].f = fopen(path, "r+");
|
|
||||||
+ if ((cachelist[i].f = fopen(path, "r+")) == NULL)
|
|
||||||
+ xlog(L_ERROR, "cache_open: Unable to open '%s': errno %d (%s)",
|
|
||||||
+ path, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -up nfs-utils-1.2.1/utils/mountd/Makefile.am.orig nfs-utils-1.2.1/utils/mountd/Makefile.am
|
|
||||||
--- nfs-utils-1.2.1/utils/mountd/Makefile.am.orig 2009-11-04 06:13:56.000000000 -0500
|
|
||||||
+++ nfs-utils-1.2.1/utils/mountd/Makefile.am 2009-11-11 14:01:56.421960000 -0500
|
|
||||||
@@ -8,7 +8,7 @@ KPREFIX = @kprefix@
|
|
||||||
sbin_PROGRAMS = mountd
|
|
||||||
|
|
||||||
mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
|
|
||||||
- svc_run.c fsloc.c mountd.h
|
|
||||||
+ svc_run.c fsloc.c v4root.c mountd.h
|
|
||||||
mountd_LDADD = ../../support/export/libexport.a \
|
|
||||||
../../support/nfs/libnfs.a \
|
|
||||||
../../support/misc/libmisc.a \
|
|
||||||
diff -up /dev/null nfs-utils-1.2.1/utils/mountd/v4root.c
|
|
||||||
--- /dev/null 2009-11-11 11:00:17.075766506 -0500
|
|
||||||
+++ nfs-utils-1.2.1/utils/mountd/v4root.c 2009-11-11 14:02:39.699100000 -0500
|
|
||||||
@@ -0,0 +1,432 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (C) 2009 Red Hat <nfs@redhat.com>
|
|
||||||
+ *
|
|
||||||
+ * support/export/v4root.c
|
|
||||||
+ *
|
|
||||||
+ * Routines used to support NFSv4 pseudo roots
|
|
||||||
+ *
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_CONFIG_H
|
|
||||||
+#include <config.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#include <sys/types.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
+#include <sys/queue.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
+
|
|
||||||
+#include <uuid/uuid.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+
|
|
||||||
+#include "xlog.h"
|
|
||||||
+#include "exportfs.h"
|
|
||||||
+#include "nfslib.h"
|
|
||||||
+#include "misc.h"
|
|
||||||
+#include "v4root.h"
|
|
||||||
+
|
|
||||||
+#ifndef _PATH_PSEUDO_ROOT
|
|
||||||
+#define _PATH_PSEUDO_ROOT "/"
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifndef _PSEUDO_ROOT_FSID
|
|
||||||
+#define _PSEUDO_ROOT_FSID 0
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+extern int get_uuid(char *path, char *uuid, int uuidlen, char *u);
|
|
||||||
+
|
|
||||||
+#define HASH_TABLE_SIZE 1021
|
|
||||||
+typedef struct _hash_head {
|
|
||||||
+ TAILQ_HEAD(export_list, _exports_t) h_head;
|
|
||||||
+} hash_head;
|
|
||||||
+hash_head exports_tbl[HASH_TABLE_SIZE];
|
|
||||||
+
|
|
||||||
+typedef struct _exports_t {
|
|
||||||
+ TAILQ_ENTRY(_exports_t) list;
|
|
||||||
+ char *path;
|
|
||||||
+ hash_head *head;
|
|
||||||
+ char uuid_len;
|
|
||||||
+ char uuid[sizeof(uuid_t)];
|
|
||||||
+ struct exportent p_export;
|
|
||||||
+} exports_t;
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static exports_t *hash_export_lookup(char *, unsigned int);
|
|
||||||
+static void hash_export_add(struct _exports_t *, int);
|
|
||||||
+static void hash_mount_free(void);
|
|
||||||
+
|
|
||||||
+static inline unsigned int strtoint(char *str, int len)
|
|
||||||
+{
|
|
||||||
+ unsigned int n = 0;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ for (i=0; i < len; i++)
|
|
||||||
+ n+=((int)str[i])*i;
|
|
||||||
+ return n;
|
|
||||||
+}
|
|
||||||
+static inline int hashint(unsigned int num)
|
|
||||||
+{
|
|
||||||
+ return num % HASH_TABLE_SIZE;
|
|
||||||
+}
|
|
||||||
+#define HASH(_s, _l) hashint(strtoint((_s), (_l)))
|
|
||||||
+void v4root_set(void);
|
|
||||||
+void v4root_unset(void);
|
|
||||||
+static int v4root_support(void);
|
|
||||||
+
|
|
||||||
+static struct exportent *v4root_create(char *, nfs_export *);
|
|
||||||
+
|
|
||||||
+int v4root_needed;
|
|
||||||
+
|
|
||||||
+static nfs_export pr_export = {
|
|
||||||
+ .m_next = NULL,
|
|
||||||
+ .m_client = NULL,
|
|
||||||
+ .m_export = {
|
|
||||||
+ .e_hostname = "*",
|
|
||||||
+ .e_path = _PATH_PSEUDO_ROOT,
|
|
||||||
+ .e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
|
|
||||||
+ | NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
|
|
||||||
+ | NFSEXP_CROSSMOUNT | NFSEXP_V4ROOT,
|
|
||||||
+ .e_anonuid = 65534,
|
|
||||||
+ .e_anongid = 65534,
|
|
||||||
+ .e_squids = NULL,
|
|
||||||
+ .e_nsquids = 0,
|
|
||||||
+ .e_sqgids = NULL,
|
|
||||||
+ .e_nsqgids = 0,
|
|
||||||
+ .e_fsid = 0,
|
|
||||||
+ .e_mountpoint = NULL,
|
|
||||||
+ },
|
|
||||||
+ .m_exported = 0,
|
|
||||||
+ .m_xtabent = 1,
|
|
||||||
+ .m_mayexport = 1,
|
|
||||||
+ .m_changed = 0,
|
|
||||||
+ .m_warned = 0,
|
|
||||||
+};
|
|
||||||
+static nfs_export *pseudo_root;
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Return the number '/' in the path
|
|
||||||
+ */
|
|
||||||
+inline static int slash_count(char *path)
|
|
||||||
+{
|
|
||||||
+ int i, slashs=0;
|
|
||||||
+
|
|
||||||
+ for (i=0; i < strlen(path); i++) {
|
|
||||||
+ if (path[i] == '/')
|
|
||||||
+ slashs++;
|
|
||||||
+ }
|
|
||||||
+ return slashs;
|
|
||||||
+}
|
|
||||||
+/*
|
|
||||||
+ * Make sure the kernel has pseudo root support.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+v4root_support()
|
|
||||||
+{
|
|
||||||
+ static int kernel_support = -1;
|
|
||||||
+ char *ptr, version[64];
|
|
||||||
+ int major, minor;
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
+ if (kernel_support != -1)
|
|
||||||
+ return kernel_support;
|
|
||||||
+
|
|
||||||
+ kernel_support = 0;
|
|
||||||
+ fp = fopen("/proc/fs/nfsd/exports", "r");
|
|
||||||
+ if (fp == NULL)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ ptr = fgets(version, 64, fp);
|
|
||||||
+ fclose(fp);
|
|
||||||
+ if (ptr == NULL)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ while(*ptr && isdigit(*ptr) == 0)
|
|
||||||
+ ptr++;
|
|
||||||
+ if (*ptr == '\0')
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ major = minor = 0;
|
|
||||||
+ sscanf(ptr, " %d.%d",&major, &minor);
|
|
||||||
+ if (major >= 1 && minor >= 2)
|
|
||||||
+ kernel_support = 1;
|
|
||||||
+out:
|
|
||||||
+ if (!kernel_support) {
|
|
||||||
+ xlog(L_WARNING, "Kernel does not have pseudo root support.");
|
|
||||||
+ xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
|
|
||||||
+ xlog(L_WARNING, "is specfied in /etc/exports file.");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return kernel_support;
|
|
||||||
+}
|
|
||||||
+/*
|
|
||||||
+ * Build a table of pseudo exports by running through
|
|
||||||
+ * the real export looking at the components of the path
|
|
||||||
+ * that make up the export. Those path components, if
|
|
||||||
+ * not exported, will become pseudo exports allowing them
|
|
||||||
+ * to be found when the kernel does an upcall looking for
|
|
||||||
+ * components of the v4 mount.
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+v4root_set()
|
|
||||||
+{
|
|
||||||
+ nfs_export *exp, *nxt;
|
|
||||||
+ struct exportent *proot;
|
|
||||||
+ int i, insecure = 0;
|
|
||||||
+ char *path, *ptr;
|
|
||||||
+ char *hostname;
|
|
||||||
+
|
|
||||||
+ if (!v4root_needed)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (!v4root_support())
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ pseudo_root = &pr_export;
|
|
||||||
+ if ((proot = v4root_create(_PATH_PSEUDO_ROOT, pseudo_root)) == NULL) {
|
|
||||||
+ xlog(L_WARNING, "v4root_set: Unable to create"
|
|
||||||
+ "pseudo export for '%s'", _PATH_PSEUDO_ROOT);
|
|
||||||
+ pseudo_root = NULL;
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < MCL_MAXTYPES; i++) {
|
|
||||||
+ for (exp = exportlist[i].p_head; exp; exp = nxt) {
|
|
||||||
+ nxt = exp->m_next;
|
|
||||||
+ hostname = exp->m_export.e_hostname;
|
|
||||||
+
|
|
||||||
+ path = strdup(exp->m_export.e_path);
|
|
||||||
+ ptr = path + 1;
|
|
||||||
+ while ((ptr = strchr(ptr, '/')) != NULL) {
|
|
||||||
+ *ptr = '\0';
|
|
||||||
+ if (export_lookup(hostname, path, 0) == NULL)
|
|
||||||
+ if (v4root_create(path, exp) == NULL) {
|
|
||||||
+ xlog(L_WARNING, "v4root_set: Unable to create"
|
|
||||||
+ "pseudo export for '%s'", path);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ *ptr = '/';
|
|
||||||
+ ptr++;
|
|
||||||
+ }
|
|
||||||
+ /* Make note of insecure exports */
|
|
||||||
+ if (!insecure)
|
|
||||||
+ insecure = (exp->m_export.e_flags & NFSEXP_INSECURE_PORT);
|
|
||||||
+
|
|
||||||
+ free(path);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ /*
|
|
||||||
+ * If there are any insecure exports, the pseudo root
|
|
||||||
+ * also has to be insecure
|
|
||||||
+ */
|
|
||||||
+ if (insecure) {
|
|
||||||
+ pseudo_root->m_export.e_flags |= NFSEXP_INSECURE_PORT;
|
|
||||||
+ proot->e_flags |= NFSEXP_INSECURE_PORT;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Unset the pseudo root export
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+v4root_unset()
|
|
||||||
+{
|
|
||||||
+ pseudo_root = NULL;
|
|
||||||
+ hash_mount_free();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * The kernel will do an upcall looking for the pseudo
|
|
||||||
+ * root via its fsid. When the wanted fsid equals
|
|
||||||
+ * PSEUDO_ROOT_FSID return the pseudo root export.
|
|
||||||
+ */
|
|
||||||
+struct exportent *
|
|
||||||
+v4root_chkroot(int fsidtype, unsigned int fsidnum, char *fhuuid)
|
|
||||||
+{
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if (fsidtype != FSID_NUM)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if (fsidnum != _PSEUDO_ROOT_FSID)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ return &pseudo_root->m_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Create a pseudo export, if one does not
|
|
||||||
+ * already exist.
|
|
||||||
+ */
|
|
||||||
+static struct exportent *
|
|
||||||
+v4root_create(char *path, nfs_export *exp)
|
|
||||||
+{
|
|
||||||
+ static struct exportent *p_export = NULL;
|
|
||||||
+ exports_t *pexp;
|
|
||||||
+ char uuid_len = sizeof(uuid_t);
|
|
||||||
+ char uuid[sizeof(uuid_t)];
|
|
||||||
+
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ /* Check to see if the export already exists */
|
|
||||||
+ get_uuid(path, NULL, uuid_len, uuid);
|
|
||||||
+ if ((p_export = v4root_export(uuid, uuid_len)) != NULL)
|
|
||||||
+ return p_export;
|
|
||||||
+
|
|
||||||
+ pexp = (exports_t *)malloc(sizeof(exports_t));
|
|
||||||
+ if (pexp == NULL) {
|
|
||||||
+ xlog(L_WARNING, "v4root_create: No memory for pseudo export");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ p_export = &pexp->p_export;
|
|
||||||
+ pexp->path = strdup(path);
|
|
||||||
+ if (pexp->path == 0) {
|
|
||||||
+ xlog(L_WARNING, "v4root_create: No memory for pseudo path");
|
|
||||||
+ free(pexp);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ pexp->uuid_len = uuid_len;
|
|
||||||
+ memcpy(pexp->uuid, uuid, uuid_len);
|
|
||||||
+
|
|
||||||
+ dupexportent(&pexp->p_export, &pr_export.m_export);
|
|
||||||
+ strcpy(p_export->e_path, path);
|
|
||||||
+ p_export->e_flags &= ~NFSEXP_FSID;
|
|
||||||
+ p_export->e_v4root = (void *)pexp;
|
|
||||||
+
|
|
||||||
+ hash_export_add(pexp, HASH(pexp->uuid, sizeof(uuid_t)));
|
|
||||||
+
|
|
||||||
+ xlog(D_CALL, "v4root_create: path '%s'", p_export->e_path);
|
|
||||||
+
|
|
||||||
+ return p_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * See if the pseudo export exists
|
|
||||||
+ */
|
|
||||||
+struct exportent *
|
|
||||||
+v4root_lookup(char *path, nfs_export *exp)
|
|
||||||
+{
|
|
||||||
+ static struct exportent *p_export = NULL;
|
|
||||||
+ char *epath = exp->m_export.e_path;
|
|
||||||
+ int elen, plen;
|
|
||||||
+ char uuid_len = sizeof(uuid_t);
|
|
||||||
+ char uuid[sizeof(uuid_t)];
|
|
||||||
+
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ /* Path needs to be a subset of e_path */
|
|
||||||
+ elen = strlen(epath);
|
|
||||||
+ plen = strlen(path);
|
|
||||||
+ if (plen >= elen)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ if (memcmp(path, epath, plen) != 0)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ /* Now to see if the export exists */
|
|
||||||
+ get_uuid(path, NULL, uuid_len, uuid);
|
|
||||||
+ p_export = v4root_export(uuid, uuid_len);
|
|
||||||
+
|
|
||||||
+ return p_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Free a pseudo export
|
|
||||||
+ */
|
|
||||||
+void
|
|
||||||
+v4root_free(struct exportent *p_export)
|
|
||||||
+{
|
|
||||||
+ exports_t *pexp = (exports_t *)p_export->e_v4root;
|
|
||||||
+ hash_head *head = (hash_head *)pexp->head;
|
|
||||||
+
|
|
||||||
+ free(pexp->path);
|
|
||||||
+ TAILQ_REMOVE(&head->h_head, pexp, list);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Return a pseudo export that match the given uuid
|
|
||||||
+ */
|
|
||||||
+struct exportent *
|
|
||||||
+v4root_export(char *fhuuid, int uuidlen)
|
|
||||||
+{
|
|
||||||
+ struct exportent *p_export = NULL;
|
|
||||||
+ exports_t *pexp;
|
|
||||||
+ int len = MIN(uuidlen, sizeof(uuid_t));
|
|
||||||
+
|
|
||||||
+ if (pseudo_root == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ pexp = hash_export_lookup(fhuuid, len);
|
|
||||||
+ if (pexp) {
|
|
||||||
+ p_export = &pexp->p_export;
|
|
||||||
+ xlog(D_CALL, "v4root_export: path %s", p_export->e_path);
|
|
||||||
+ }
|
|
||||||
+ return p_export;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Add pseudo export to export table
|
|
||||||
+ */
|
|
||||||
+static void hash_export_add(struct _exports_t *exp, int hash)
|
|
||||||
+{
|
|
||||||
+ hash_head *head;
|
|
||||||
+
|
|
||||||
+ head = &(exports_tbl[hash]);
|
|
||||||
+ exp->head = head;
|
|
||||||
+
|
|
||||||
+ if (TAILQ_EMPTY(&head->h_head))
|
|
||||||
+ TAILQ_INSERT_HEAD(&head->h_head, exp, list);
|
|
||||||
+ else
|
|
||||||
+ TAILQ_INSERT_TAIL(&head->h_head, exp, list);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Lookup a pseudo export using the uuid and inode number
|
|
||||||
+ */
|
|
||||||
+static exports_t *
|
|
||||||
+hash_export_lookup(char *uuid, unsigned int uuidlen)
|
|
||||||
+{
|
|
||||||
+ exports_t *pexp;
|
|
||||||
+ hash_head *head;
|
|
||||||
+ int hash = HASH(uuid, uuidlen);
|
|
||||||
+
|
|
||||||
+ head = &(exports_tbl[hash]);
|
|
||||||
+
|
|
||||||
+ TAILQ_FOREACH(pexp, &head->h_head, list) {
|
|
||||||
+ if (memcmp(pexp->uuid, uuid, uuidlen) == 0)
|
|
||||||
+ return pexp;
|
|
||||||
+ }
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Free up pseudo export table
|
|
||||||
+ */
|
|
||||||
+static void hash_mount_free()
|
|
||||||
+{
|
|
||||||
+ hash_head *head;
|
|
||||||
+ exports_t *e1, *e2;
|
|
||||||
+ int hash;
|
|
||||||
+
|
|
||||||
+ for (hash=0; hash < HASH_TABLE_SIZE; hash++) {
|
|
||||||
+ head = &(exports_tbl[hash]);
|
|
||||||
+ if (head == NULL)
|
|
||||||
+ continue;
|
|
||||||
+ e1 = TAILQ_FIRST(&head->h_head);
|
|
||||||
+ while (e1 != NULL) {
|
|
||||||
+ free(e1->path);
|
|
||||||
+ e2 = TAILQ_NEXT(e1, list);
|
|
||||||
+ TAILQ_REMOVE(&head->h_head, e1, list);
|
|
||||||
+ free(e1);
|
|
||||||
+ e1 = e2;
|
|
||||||
+ }
|
|
||||||
+ TAILQ_INIT(&head->h_head);
|
|
||||||
+ }
|
|
||||||
+}
|
|
406
nfs-utils-1.2.0-v4root-rel9.patch
Normal file
406
nfs-utils-1.2.0-v4root-rel9.patch
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
diff --git a/support/export/xtab.c b/support/export/xtab.c
|
||||||
|
index 3b1dcce..2a43193 100644
|
||||||
|
--- a/support/export/xtab.c
|
||||||
|
+++ b/support/export/xtab.c
|
||||||
|
@@ -19,7 +19,9 @@
|
||||||
|
#include "exportfs.h"
|
||||||
|
#include "xio.h"
|
||||||
|
#include "xlog.h"
|
||||||
|
+#include "v4root.h"
|
||||||
|
|
||||||
|
+int v4root_needed;
|
||||||
|
static void cond_rename(char *newfile, char *oldfile);
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -36,6 +38,8 @@ xtab_read(char *xtab, char *lockfn, int is_export)
|
||||||
|
if ((lockid = xflock(lockfn, "r")) < 0)
|
||||||
|
return 0;
|
||||||
|
setexportent(xtab, "r");
|
||||||
|
+ if (is_export == 1)
|
||||||
|
+ v4root_needed = 1;
|
||||||
|
while ((xp = getexportent(is_export==0, 0)) != NULL) {
|
||||||
|
if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
|
||||||
|
!(exp = export_create(xp, is_export!=1))) {
|
||||||
|
@@ -48,6 +52,8 @@ xtab_read(char *xtab, char *lockfn, int is_export)
|
||||||
|
case 1:
|
||||||
|
exp->m_xtabent = 1;
|
||||||
|
exp->m_mayexport = 1;
|
||||||
|
+ if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
|
||||||
|
+ v4root_needed = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
exp->m_exported = -1;/* may be exported */
|
||||||
|
diff --git a/support/include/nfs/export.h b/support/include/nfs/export.h
|
||||||
|
index f7a99ba..76953ac 100644
|
||||||
|
--- a/support/include/nfs/export.h
|
||||||
|
+++ b/support/include/nfs/export.h
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
#define NFSEXP_FSID 0x2000
|
||||||
|
#define NFSEXP_CROSSMOUNT 0x4000
|
||||||
|
#define NFSEXP_NOACL 0x8000 /* reserved for possible ACL related use */
|
||||||
|
-#define NFSEXP_ALLFLAGS 0xFFFF
|
||||||
|
+#define NFSEXP_V4ROOT 0x10000
|
||||||
|
+#define NFSEXP_ALLFLAGS 0x1FFFF
|
||||||
|
|
||||||
|
#endif /* _NSF_EXPORT_H */
|
||||||
|
diff --git a/support/include/pseudoflavors.h b/support/include/pseudoflavors.h
|
||||||
|
index c21087b..c7ba8a2 100644
|
||||||
|
--- a/support/include/pseudoflavors.h
|
||||||
|
+++ b/support/include/pseudoflavors.h
|
||||||
|
@@ -15,3 +15,4 @@ struct flav_info {
|
||||||
|
|
||||||
|
extern struct flav_info flav_map[];
|
||||||
|
extern const int flav_map_size;
|
||||||
|
+extern unsigned int flavors_setall(struct exportent *ep);
|
||||||
|
diff --git a/support/include/v4root.h b/support/include/v4root.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..706c15c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/include/v4root.h
|
||||||
|
@@ -0,0 +1,15 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2009 Red Hat <nfs@redhat.com>
|
||||||
|
+ * support/include/v4root.h
|
||||||
|
+ *
|
||||||
|
+ * Support routines for dynamic pseudo roots.
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef V4ROOT_H
|
||||||
|
+#define V4ROOT_H
|
||||||
|
+
|
||||||
|
+extern int v4root_needed;
|
||||||
|
+extern void v4root_set(void);
|
||||||
|
+
|
||||||
|
+#endif /* V4ROOT_H */
|
||||||
|
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
|
||||||
|
index 1aaebf4..fe9ed3a 100644
|
||||||
|
--- a/support/nfs/exports.c
|
||||||
|
+++ b/support/nfs/exports.c
|
||||||
|
@@ -39,16 +39,18 @@ struct flav_info flav_map[] = {
|
||||||
|
{ "krb5", RPC_AUTH_GSS_KRB5 },
|
||||||
|
{ "krb5i", RPC_AUTH_GSS_KRB5I },
|
||||||
|
{ "krb5p", RPC_AUTH_GSS_KRB5P },
|
||||||
|
+ { "unix", AUTH_UNIX },
|
||||||
|
+ { "sys", AUTH_SYS },
|
||||||
|
+ { "null", AUTH_NULL },
|
||||||
|
+ { "none", AUTH_NONE },
|
||||||
|
+#ifdef NOLONGERSUPPORTED
|
||||||
|
{ "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 },
|
||||||
|
+#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const int flav_map_size = sizeof(flav_map)/sizeof(flav_map[0]);
|
||||||
|
@@ -436,6 +438,20 @@ static unsigned int parse_flavors(char *str, struct exportent *ep)
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
+unsigned int flavors_setall(struct exportent *ep)
|
||||||
|
+{
|
||||||
|
+ struct flav_info *flav;
|
||||||
|
+ unsigned int out=0;
|
||||||
|
+ int bit;
|
||||||
|
+
|
||||||
|
+ for (flav = flav_map; flav < flav_map + flav_map_size; flav++) {
|
||||||
|
+ bit = secinfo_addflavor(flav, ep);
|
||||||
|
+ if (bit < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ out |= 1<<bit;
|
||||||
|
+ }
|
||||||
|
+ return out;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* Sets the bits in @mask for the appropriate security flavor flags. */
|
||||||
|
static void setflags(int mask, unsigned int active, struct exportent *ep)
|
||||||
|
diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am
|
||||||
|
index 1e76cf8..eba81fc 100644
|
||||||
|
--- a/utils/mountd/Makefile.am
|
||||||
|
+++ b/utils/mountd/Makefile.am
|
||||||
|
@@ -8,7 +8,7 @@ KPREFIX = @kprefix@
|
||||||
|
sbin_PROGRAMS = mountd
|
||||||
|
|
||||||
|
mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
|
||||||
|
- svc_run.c fsloc.c mountd.h
|
||||||
|
+ svc_run.c fsloc.c v4root.c mountd.h
|
||||||
|
mountd_LDADD = ../../support/export/libexport.a \
|
||||||
|
../../support/nfs/libnfs.a \
|
||||||
|
../../support/misc/libmisc.a \
|
||||||
|
diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
|
||||||
|
index 5a7ff8c..2ed80bc 100644
|
||||||
|
--- a/utils/mountd/auth.c
|
||||||
|
+++ b/utils/mountd/auth.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#include "exportfs.h"
|
||||||
|
#include "mountd.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
+#include "v4root.h"
|
||||||
|
|
||||||
|
enum auth_error
|
||||||
|
{
|
||||||
|
@@ -102,6 +103,8 @@ auth_reload()
|
||||||
|
memset(&my_client, 0, sizeof(my_client));
|
||||||
|
xtab_export_read();
|
||||||
|
check_useipaddr();
|
||||||
|
+ v4root_set();
|
||||||
|
+
|
||||||
|
++counter;
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
|
||||||
|
index 888fd8c..179ef17 100644
|
||||||
|
--- a/utils/mountd/mountd.c
|
||||||
|
+++ b/utils/mountd/mountd.c
|
||||||
|
@@ -540,6 +540,10 @@ get_exportlist(void)
|
||||||
|
|
||||||
|
for (i = 0; i < MCL_MAXTYPES; i++) {
|
||||||
|
for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
|
||||||
|
+ /* Don't show pseudo exports */
|
||||||
|
+ if (exp->m_export.e_flags & NFSEXP_V4ROOT)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
for (e = elist; e != NULL; e = e->ex_next) {
|
||||||
|
if (!strcmp(exp->m_export.e_path, e->ex_dir))
|
||||||
|
break;
|
||||||
|
diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..817dfb4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/utils/mountd/v4root.c
|
||||||
|
@@ -0,0 +1,228 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2009 Red Hat <nfs@redhat.com>
|
||||||
|
+ *
|
||||||
|
+ * support/export/v4root.c
|
||||||
|
+ *
|
||||||
|
+ * Routines used to support NFSv4 pseudo roots
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_CONFIG_H
|
||||||
|
+#include <config.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <sys/queue.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+
|
||||||
|
+#include "xlog.h"
|
||||||
|
+#include "exportfs.h"
|
||||||
|
+#include "nfslib.h"
|
||||||
|
+#include "misc.h"
|
||||||
|
+#include "pseudoflavors.h"
|
||||||
|
+#include "v4root.h"
|
||||||
|
+
|
||||||
|
+#ifndef _PATH_PSEUDO_ROOT
|
||||||
|
+#define _PATH_PSEUDO_ROOT "/"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef _PSEUDO_ROOT_FSID
|
||||||
|
+#define _PSEUDO_ROOT_FSID 0
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+void v4root_set(void);
|
||||||
|
+void v4root_unset(void);
|
||||||
|
+static int v4root_support(void);
|
||||||
|
+
|
||||||
|
+static struct exportent *v4root_create(char *, nfs_export *);
|
||||||
|
+
|
||||||
|
+int v4root_needed;
|
||||||
|
+static nfs_export pseudo_root = {
|
||||||
|
+ .m_next = NULL,
|
||||||
|
+ .m_client = NULL,
|
||||||
|
+ .m_export = {
|
||||||
|
+ .e_hostname = "*",
|
||||||
|
+ .e_path = _PATH_PSEUDO_ROOT,
|
||||||
|
+ .e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
|
||||||
|
+ | NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
|
||||||
|
+ | NFSEXP_CROSSMOUNT | NFSEXP_V4ROOT,
|
||||||
|
+ .e_anonuid = 65534,
|
||||||
|
+ .e_anongid = 65534,
|
||||||
|
+ .e_squids = NULL,
|
||||||
|
+ .e_nsquids = 0,
|
||||||
|
+ .e_sqgids = NULL,
|
||||||
|
+ .e_nsqgids = 0,
|
||||||
|
+ .e_fsid = 0,
|
||||||
|
+ .e_mountpoint = NULL,
|
||||||
|
+ .e_secinfo[0].flav = NULL,
|
||||||
|
+ },
|
||||||
|
+ .m_exported = 0,
|
||||||
|
+ .m_xtabent = 1,
|
||||||
|
+ .m_mayexport = 1,
|
||||||
|
+ .m_changed = 0,
|
||||||
|
+ .m_warned = 0,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Create a pseudo export
|
||||||
|
+ */
|
||||||
|
+static struct exportent *
|
||||||
|
+v4root_create(char *path, nfs_export *export)
|
||||||
|
+{
|
||||||
|
+ nfs_export *exp;
|
||||||
|
+ struct exportent eep;
|
||||||
|
+ struct exportent *curexp = &export->m_export;
|
||||||
|
+
|
||||||
|
+ dupexportent(&eep, curexp);
|
||||||
|
+ eep.e_hostname = strdup(curexp->e_hostname);
|
||||||
|
+ strncpy(eep.e_path, path, sizeof(eep.e_path));
|
||||||
|
+ exp = export_create(&eep, 0);
|
||||||
|
+ if (exp == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ exp->m_export.e_flags |= NFSEXP_V4ROOT;
|
||||||
|
+ if (strcmp(path, _PATH_PSEUDO_ROOT) != 0)
|
||||||
|
+ exp->m_export.e_flags &= ~NFSEXP_FSID;
|
||||||
|
+
|
||||||
|
+ xlog(D_CALL, "v4root_create: path '%s'", exp->m_export.e_path);
|
||||||
|
+
|
||||||
|
+ return &exp->m_export;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Make sure the kernel has pseudo root support.
|
||||||
|
+ */
|
||||||
|
+static int
|
||||||
|
+v4root_support()
|
||||||
|
+{
|
||||||
|
+ static int kernel_support = -1;
|
||||||
|
+ char *ptr, version[64];
|
||||||
|
+ int major, minor;
|
||||||
|
+ FILE *fp;
|
||||||
|
+
|
||||||
|
+ if (kernel_support != -1)
|
||||||
|
+ return kernel_support;
|
||||||
|
+
|
||||||
|
+ kernel_support = 0;
|
||||||
|
+ fp = fopen("/proc/fs/nfsd/exports", "r");
|
||||||
|
+ if (fp == NULL)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ ptr = fgets(version, 64, fp);
|
||||||
|
+ fclose(fp);
|
||||||
|
+ if (ptr == NULL)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ while(*ptr && isdigit(*ptr) == 0)
|
||||||
|
+ ptr++;
|
||||||
|
+ if (*ptr == '\0')
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ major = minor = 0;
|
||||||
|
+ sscanf(ptr, " %d.%d",&major, &minor);
|
||||||
|
+ if (major >= 1 && minor >= 2)
|
||||||
|
+ kernel_support = 1;
|
||||||
|
+out:
|
||||||
|
+ if (!kernel_support) {
|
||||||
|
+ xlog(L_WARNING, "Kernel does not have pseudo root support.");
|
||||||
|
+ xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
|
||||||
|
+ xlog(L_WARNING, "is specfied in /etc/exports file.");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return kernel_support;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Create pseudo exports by running through the real export
|
||||||
|
+ * looking at the components of the path that make up the export.
|
||||||
|
+ * Those path components, if not exported, will become pseudo
|
||||||
|
+ * exports allowing them to be found when the kernel does an upcall
|
||||||
|
+ * looking for components of the v4 mount.
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+v4root_set()
|
||||||
|
+{
|
||||||
|
+ nfs_export *exp, *nxt;
|
||||||
|
+ struct exportent *proot;
|
||||||
|
+ int i, insecure = 0, secflavors = 0;
|
||||||
|
+ char *path, *ptr;
|
||||||
|
+ char *hostname;
|
||||||
|
+
|
||||||
|
+ if (!v4root_needed)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (!v4root_support())
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ proot = v4root_create(_PATH_PSEUDO_ROOT, &pseudo_root);
|
||||||
|
+ if (proot == NULL) {
|
||||||
|
+ xlog(L_WARNING, "v4root_set: Unable to create "
|
||||||
|
+ "pseudo export for '%s'", _PATH_PSEUDO_ROOT);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < MCL_MAXTYPES; i++) {
|
||||||
|
+ for (exp = exportlist[i].p_head; exp; exp = nxt) {
|
||||||
|
+ nxt = exp->m_next;
|
||||||
|
+ hostname = exp->m_export.e_hostname;
|
||||||
|
+
|
||||||
|
+ path = strdup(exp->m_export.e_path);
|
||||||
|
+ ptr = path + 1;
|
||||||
|
+ while ((ptr = strchr(ptr, '/')) != NULL) {
|
||||||
|
+ *ptr = '\0';
|
||||||
|
+ if (export_lookup(hostname, path, 0) == NULL)
|
||||||
|
+ if (v4root_create(path, exp) == NULL) {
|
||||||
|
+ xlog(L_WARNING, "v4root_set: Unable to create "
|
||||||
|
+ "pseudo export for '%s'", path);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ *ptr = '/';
|
||||||
|
+ ptr++;
|
||||||
|
+ }
|
||||||
|
+ /* Make note of insecure exports */
|
||||||
|
+ if (!insecure)
|
||||||
|
+ insecure = (exp->m_export.e_flags & NFSEXP_INSECURE_PORT);
|
||||||
|
+
|
||||||
|
+ /* Make note of security flavors being set */
|
||||||
|
+ if (!secflavors)
|
||||||
|
+ secflavors = (exp->m_export.e_secinfo[0].flav != NULL);
|
||||||
|
+
|
||||||
|
+ free(path);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (insecure && secflavors) {
|
||||||
|
+ xlog(L_WARNING, "WARNING: The 'sec=' and 'insecure' export options "
|
||||||
|
+ "are incompatible, causing the security flavors set by "
|
||||||
|
+ "'sec=' to be ignored on V4 exports");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If there are any insecure exports, the pseudo root
|
||||||
|
+ * also has to be insecure
|
||||||
|
+ */
|
||||||
|
+ if (insecure) {
|
||||||
|
+ proot->e_flags |= NFSEXP_INSECURE_PORT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Make sure the pseudo root is accessible from all
|
||||||
|
+ * security flavors unless the insecure port is set,
|
||||||
|
+ * which cause the kernel to silently fail v4 mounts
|
||||||
|
+ * with security flavors set.
|
||||||
|
+ */
|
||||||
|
+ if (secflavors && !insecure) {
|
||||||
|
+ if (!flavors_setall(proot)) {
|
||||||
|
+ xlog(L_WARNING, "v4root_set: Unable to set security "
|
||||||
|
+ "flavors on pseudo root");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
|
|||||||
Name: nfs-utils
|
Name: nfs-utils
|
||||||
URL: http://sourceforge.net/projects/nfs
|
URL: http://sourceforge.net/projects/nfs
|
||||||
Version: 1.2.1
|
Version: 1.2.1
|
||||||
Release: 3%{?dist}
|
Release: 4%{?dist}
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
|
|
||||||
# group all 32bit related archs
|
# group all 32bit related archs
|
||||||
@ -22,7 +22,7 @@ Patch00: nfs-utils-1.0.5-statdpath.patch
|
|||||||
Patch01: nfs-utils-1.1.0-smnotify-path.patch
|
Patch01: nfs-utils-1.1.0-smnotify-path.patch
|
||||||
Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch
|
Patch02: nfs-utils-1.1.0-exp-subtree-warn-off.patch
|
||||||
|
|
||||||
Patch200: nfs-utils-1.2.0-v4root-rel8.patch
|
Patch200: nfs-utils-1.2.0-v4root-rel9.patch
|
||||||
Patch201: nfs-utils-1.2.1-nfsd-bootfail.patch
|
Patch201: nfs-utils-1.2.1-nfsd-bootfail.patch
|
||||||
|
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
@ -248,6 +248,9 @@ fi
|
|||||||
%attr(4755,root,root) /sbin/umount.nfs4
|
%attr(4755,root,root) /sbin/umount.nfs4
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Dec 7 2009 Steve Dickson <steved@redhat.com> 1.2.1-4
|
||||||
|
- Updated to the latest pseudo root release (rel9).
|
||||||
|
|
||||||
* Thu Nov 12 2009 Steve Dickson <steved@redhat.com> 1.2.1-3
|
* Thu Nov 12 2009 Steve Dickson <steved@redhat.com> 1.2.1-3
|
||||||
- Stop rpc.nfsd from failing to startup when the network
|
- Stop rpc.nfsd from failing to startup when the network
|
||||||
is down (bz 532270)
|
is down (bz 532270)
|
||||||
|
Loading…
Reference in New Issue
Block a user