2021-02-19 20:09:09

by Steve Dickson

[permalink] [raw]
Subject: [PATCH 2/7] exportd: Moved cache upcalls routines into libexport.a

Move the cache management code into libexport.a
so both mountd and exportd can use it.

Introduce cache_proccess_loop() which will
be used by exportd, instead of my_svc_run().

Signed-off-by: Steve Dickson <[email protected]>
---
support/export/Makefile.am | 3 +-
{utils/mountd => support/export}/auth.c | 4 +-
{utils/mountd => support/export}/cache.c | 46 +++++++++++++++++++++--
support/export/export.h | 34 +++++++++++++++++
{utils/mountd => support/export}/v4root.c | 0
utils/exportd/Makefile.am | 8 +++-
utils/exportd/exportd.c | 30 ++++++++++++++-
utils/mountd/Makefile.am | 4 +-
8 files changed, 118 insertions(+), 11 deletions(-)
rename {utils/mountd => support/export}/auth.c (99%)
rename {utils/mountd => support/export}/cache.c (98%)
create mode 100644 support/export/export.h
rename {utils/mountd => support/export}/v4root.c (100%)

diff --git a/support/export/Makefile.am b/support/export/Makefile.am
index 13f7a49..7de82a8 100644
--- a/support/export/Makefile.am
+++ b/support/export/Makefile.am
@@ -11,7 +11,8 @@ EXTRA_DIST = mount.x

noinst_LIBRARIES = libexport.a
libexport_a_SOURCES = client.c export.c hostname.c \
- xtab.c mount_clnt.c mount_xdr.c
+ xtab.c mount_clnt.c mount_xdr.c \
+ cache.c auth.c v4root.c
BUILT_SOURCES = $(GENFILES)

noinst_HEADERS = mount.h
diff --git a/utils/mountd/auth.c b/support/export/auth.c
similarity index 99%
rename from utils/mountd/auth.c
rename to support/export/auth.c
index 67627f7..0bfa77d 100644
--- a/utils/mountd/auth.c
+++ b/support/export/auth.c
@@ -22,7 +22,7 @@
#include "misc.h"
#include "nfslib.h"
#include "exportfs.h"
-#include "mountd.h"
+#include "export.h"
#include "v4root.h"

enum auth_error
@@ -43,11 +43,13 @@ extern int use_ipaddr;

extern struct state_paths etab;

+/*
void
auth_init(void)
{
auth_reload();
}
+*/

/*
* A client can match many different netgroups and it's tough to know
diff --git a/utils/mountd/cache.c b/support/export/cache.c
similarity index 98%
rename from utils/mountd/cache.c
rename to support/export/cache.c
index a81e820..f1569af 100644
--- a/utils/mountd/cache.c
+++ b/support/export/cache.c
@@ -30,11 +30,14 @@
#include "nfsd_path.h"
#include "nfslib.h"
#include "exportfs.h"
-#include "mountd.h"
-#include "fsloc.h"
+#include "export.h"
#include "pseudoflavors.h"
#include "xcommon.h"

+#ifdef HAVE_JUNCTION_SUPPORT
+#include "fsloc.h"
+#endif
+
#ifdef USE_BLKID
#include "blkid/blkid.h"
#endif
@@ -44,6 +47,7 @@
*/
void cache_set_fds(fd_set *fdset);
int cache_process_req(fd_set *readfds);
+void cache_process_loop(void);

enum nfsd_fsid {
FSID_DEV = 0,
@@ -909,6 +913,7 @@ out:
xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL);
}

+#ifdef HAVE_JUNCTION_SUPPORT
static void write_fsloc(char **bp, int *blen, struct exportent *ep)
{
struct servers *servers;
@@ -931,7 +936,7 @@ static void write_fsloc(char **bp, int *blen, struct exportent *ep)
qword_addint(bp, blen, servers->h_referral);
release_replicas(servers);
}
-
+#endif
static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask)
{
struct sec_entry *p;
@@ -974,7 +979,10 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain,
qword_addint(&bp, &blen, exp->e_anonuid);
qword_addint(&bp, &blen, exp->e_anongid);
qword_addint(&bp, &blen, exp->e_fsid);
+
+#ifdef HAVE_JUNCTION_SUPPORT
write_fsloc(&bp, &blen, exp);
+#endif
write_secinfo(&bp, &blen, exp, flag_mask);
if (exp->e_uuid == NULL || different_fs) {
char u[16];
@@ -1509,6 +1517,38 @@ int cache_process_req(fd_set *readfds)
return cnt;
}

+/**
+ * cache_process_loop - process incoming upcalls
+ */
+void cache_process_loop(void)
+{
+ fd_set readfds;
+ int selret;
+
+ FD_ZERO(&readfds);
+
+ for (;;) {
+
+ cache_set_fds(&readfds);
+
+ selret = select(FD_SETSIZE, &readfds,
+ (void *) 0, (void *) 0, (struct timeval *) 0);
+
+
+ switch (selret) {
+ case -1:
+ if (errno == EINTR || errno == ECONNREFUSED
+ || errno == ENETUNREACH || errno == EHOSTUNREACH)
+ continue;
+ xlog(L_ERROR, "my_svc_run() - select: %m");
+ return;
+
+ default:
+ cache_process_req(&readfds);
+ }
+ }
+}
+

/*
* Give IP->domain and domain+path->options to kernel
diff --git a/support/export/export.h b/support/export/export.h
new file mode 100644
index 0000000..4296db1
--- /dev/null
+++ b/support/export/export.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 Red Hat <[email protected]>
+ *
+ * support/export/export.h
+ *
+ * Declarations for export support
+ */
+
+#ifndef EXPORT_H
+#define EXPORT_H
+
+#include "nfslib.h"
+
+unsigned int auth_reload(void);
+nfs_export * auth_authenticate(const char *what,
+ const struct sockaddr *caller,
+ const char *path);
+
+void cache_open(void);
+void cache_process_loop(void);
+
+struct nfs_fh_len *
+ cache_get_filehandle(nfs_export *exp, int len, char *p);
+int cache_export(nfs_export *exp, char *path);
+
+bool ipaddr_client_matches(nfs_export *exp, struct addrinfo *ai);
+bool namelist_client_matches(nfs_export *exp, char *dom);
+bool client_matches(nfs_export *exp, char *dom, struct addrinfo *ai);
+
+static inline bool is_ipaddr_client(char *dom)
+{
+ return dom[0] == '$';
+}
+#endif /* EXPORT__H */
diff --git a/utils/mountd/v4root.c b/support/export/v4root.c
similarity index 100%
rename from utils/mountd/v4root.c
rename to support/export/v4root.c
diff --git a/utils/exportd/Makefile.am b/utils/exportd/Makefile.am
index 6e61267..eb0f0a8 100644
--- a/utils/exportd/Makefile.am
+++ b/utils/exportd/Makefile.am
@@ -10,9 +10,13 @@ KPREFIX = @kprefix@
sbin_PROGRAMS = exportd

exportd_SOURCES = exportd.c
-exportd_LDADD = ../../support/nfs/libnfs.la
+exportd_LDADD = ../../support/export/libexport.a \
+ ../../support/nfs/libnfs.la \
+ ../../support/misc/libmisc.a \
+ $(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD)

-exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS)
+exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
+ -I$(top_srcdir)/support/export

MAINTAINERCLEANFILES = Makefile.in

diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
index 3a3dea6..2f67e3b 100644
--- a/utils/exportd/exportd.c
+++ b/utils/exportd/exportd.c
@@ -18,7 +18,16 @@

#include "nfslib.h"
#include "conffile.h"
+#include "exportfs.h"
+#include "export.h"

+extern void my_svc_run(void);
+
+struct state_paths etab;
+struct state_paths rmtab;
+
+int manage_gids;
+int use_ipaddr = -1;

static struct option longopts[] =
{
@@ -36,7 +45,7 @@ inline static void set_signals(void);
static void
killer (int sig)
{
- xlog (L_NOTICE, "Caught signal %d, un-registering and exiting.", sig);
+ xlog (L_NOTICE, "Caught signal %d, exiting.", sig);
exit(0);
}
static void
@@ -110,12 +119,29 @@ main(int argc, char **argv)

}

+ if (!setup_state_path_names(progname, ETAB, ETABTMP, ETABLCK, &etab))
+ return 1;
+ if (!setup_state_path_names(progname, RMTAB, RMTABTMP, RMTABLCK, &rmtab))
+ return 1;
+
if (!foreground)
xlog_stderr(0);

daemon_init(foreground);

set_signals();
-
daemon_ready();
+
+ /* Open files now to avoid sharing descriptors among forked processes */
+ cache_open();
+
+ /* Process incoming upcalls */
+ cache_process_loop();
+
+ xlog(L_ERROR, "%s: process loop terminated unexpectedly. Exiting...\n",
+ progname);
+
+ free_state_path_names(&etab);
+ free_state_path_names(&rmtab);
+ exit(1);
}
diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am
index 18610f1..cac3275 100644
--- a/utils/mountd/Makefile.am
+++ b/utils/mountd/Makefile.am
@@ -13,8 +13,8 @@ KPREFIX = @kprefix@
sbin_PROGRAMS = mountd

noinst_HEADERS = fsloc.h
-mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
- svc_run.c fsloc.c v4root.c mountd.h
+mountd_SOURCES = mountd.c mount_dispatch.c rmtab.c \
+ svc_run.c fsloc.c mountd.h
mountd_LDADD = ../../support/export/libexport.a \
../../support/nfs/libnfs.la \
../../support/misc/libmisc.a \
--
2.29.2


2021-02-23 16:17:19

by Daniel Kobras

[permalink] [raw]
Subject: [PATCH] exportd: server-side gid management

Ported manage-gids option from mountd

Signed-off-by: Daniel Kobras <[email protected]>
---
Hi Steve!

Option --manage-gids should still be useful with NFSv4 and AUTH_SYS, but
commit 15dc0bead10d20c31e72ca94ce21eb66dc3528d5 does not allow to actually
control the global variable manage_gids from exportd. I assume something
like the following was intended?

Kind regards,

Daniel

nfs.conf | 1 +
utils/exportd/exportd.c | 8 +++++++-
utils/exportd/exportd.man | 16 ++++++++++++++++
3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/nfs.conf b/nfs.conf
index bebb2e3d..e69ec16d 100644
--- a/nfs.conf
+++ b/nfs.conf
@@ -31,6 +31,7 @@
#
[exportd]
# debug="all|auth|call|general|parse"
+# manage-gids=n
# state-directory-path=/var/lib/nfs
# threads=1
[mountd]
diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
index 7130bcbf..0d7782be 100644
--- a/utils/exportd/exportd.c
+++ b/utils/exportd/exportd.c
@@ -42,6 +42,7 @@ static struct option longopts[] =
{ "foreground", 0, 0, 'F' },
{ "debug", 1, 0, 'd' },
{ "help", 0, 0, 'h' },
+ { "manage-gids", 0, 0, 'g' },
{ "num-threads", 1, 0, 't' },
{ NULL, 0, 0, 0 }
};
@@ -174,6 +175,7 @@ usage(const char *prog, int n)
{
fprintf(stderr,
"Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n"
+" [-g|--manage-gids]\n"
" [-s|--state-directory-path path]\n"
" [-t num|--num-threads=num]\n", prog);
exit(n);
@@ -188,6 +190,7 @@ read_exportd_conf(char *progname, char **argv)

xlog_set_debug(progname);

+ manage_gids = conf_get_bool("exportd", "manage-gids", manage_gids);
num_threads = conf_get_num("exportd", "threads", num_threads);

s = conf_get_str("exportd", "state-directory-path");
@@ -214,7 +217,7 @@ main(int argc, char **argv)
/* Read in config setting */
read_exportd_conf(progname, argv);

- while ((c = getopt_long(argc, argv, "d:fhs:t:", longopts, NULL)) != EOF) {
+ while ((c = getopt_long(argc, argv, "d:fghs:t:", longopts, NULL)) != EOF) {
switch (c) {
case 'd':
xlog_sconfig(optarg, 1);
@@ -222,6 +225,9 @@ main(int argc, char **argv)
case 'f':
foreground++;
break;
+ case 'g':
+ manage_gids = 1;
+ break;
case 'h':
usage(progname, 0);
break;
diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man
index 1d65b5e0..d7884562 100644
--- a/utils/exportd/exportd.man
+++ b/utils/exportd/exportd.man
@@ -51,6 +51,21 @@ spawns. The default is 1 thread, which is probably enough. More
threads are usually only needed for NFS servers which need to handle
mount storms of hundreds of NFS mounts in a few seconds, or when
your DNS server is slow or unreliable.
+.TP
+.BR \-g " or " \-\-manage-gids
+Accept requests from the kernel to map user id numbers into lists of
+group id numbers for use in access control. An NFS request will
+normally (except when using Kerberos or other cryptographic
+authentication) contain a user-id and a list of group-ids. Due to a
+limitation in the NFS protocol, at most 16 groups ids can be listed.
+If you use the
+.B \-g
+flag, then the list of group ids received from the client will be
+replaced by a list of group ids determined by an appropriate lookup on
+the server. Note that the 'primary' group id is not affected so a
+.B newgroup
+command on the client will still be effective. This function requires
+a Linux Kernel with version at least 2.6.21.
.SH CONFIGURATION FILE
Many of the options that can be set on the command line can also be
controlled through values set in the
@@ -63,6 +78,7 @@ configuration file.
Values recognized in the
.B [exportd]
section include
+.BR manage-gids ", and"
.B debug
which each have the same effect as the option with the same name.
.SH FILES
--
2.25.1


--
Puzzle ITC Deutschland GmbH
Sitz der Gesellschaft: Eisenbahnstra?e 1, 72072
T?bingen

Eingetragen am Amtsgericht Stuttgart HRB 765802
Gesch?ftsf?hrer:
Lukas Kallies, Daniel Kobras, Mark Pr?hl

2021-03-05 00:58:24

by Steve Dickson

[permalink] [raw]
Subject: Re: [PATCH] exportd: server-side gid management



On 2/23/21 11:13 AM, Daniel Kobras wrote:
> Ported manage-gids option from mountd
>
> Signed-off-by: Daniel Kobras <[email protected]>
Committed... Thanks!

steved.
> ---
> Hi Steve!
>
> Option --manage-gids should still be useful with NFSv4 and AUTH_SYS, but
> commit 15dc0bead10d20c31e72ca94ce21eb66dc3528d5 does not allow to actually
> control the global variable manage_gids from exportd. I assume something
> like the following was intended?
>
> Kind regards,
>
> Daniel
>
> nfs.conf | 1 +
> utils/exportd/exportd.c | 8 +++++++-
> utils/exportd/exportd.man | 16 ++++++++++++++++
> 3 files changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/nfs.conf b/nfs.conf
> index bebb2e3d..e69ec16d 100644
> --- a/nfs.conf
> +++ b/nfs.conf
> @@ -31,6 +31,7 @@
> #
> [exportd]
> # debug="all|auth|call|general|parse"
> +# manage-gids=n
> # state-directory-path=/var/lib/nfs
> # threads=1
> [mountd]
> diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
> index 7130bcbf..0d7782be 100644
> --- a/utils/exportd/exportd.c
> +++ b/utils/exportd/exportd.c
> @@ -42,6 +42,7 @@ static struct option longopts[] =
> { "foreground", 0, 0, 'F' },
> { "debug", 1, 0, 'd' },
> { "help", 0, 0, 'h' },
> + { "manage-gids", 0, 0, 'g' },
> { "num-threads", 1, 0, 't' },
> { NULL, 0, 0, 0 }
> };
> @@ -174,6 +175,7 @@ usage(const char *prog, int n)
> {
> fprintf(stderr,
> "Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n"
> +" [-g|--manage-gids]\n"
> " [-s|--state-directory-path path]\n"
> " [-t num|--num-threads=num]\n", prog);
> exit(n);
> @@ -188,6 +190,7 @@ read_exportd_conf(char *progname, char **argv)
>
> xlog_set_debug(progname);
>
> + manage_gids = conf_get_bool("exportd", "manage-gids", manage_gids);
> num_threads = conf_get_num("exportd", "threads", num_threads);
>
> s = conf_get_str("exportd", "state-directory-path");
> @@ -214,7 +217,7 @@ main(int argc, char **argv)
> /* Read in config setting */
> read_exportd_conf(progname, argv);
>
> - while ((c = getopt_long(argc, argv, "d:fhs:t:", longopts, NULL)) != EOF) {
> + while ((c = getopt_long(argc, argv, "d:fghs:t:", longopts, NULL)) != EOF) {
> switch (c) {
> case 'd':
> xlog_sconfig(optarg, 1);
> @@ -222,6 +225,9 @@ main(int argc, char **argv)
> case 'f':
> foreground++;
> break;
> + case 'g':
> + manage_gids = 1;
> + break;
> case 'h':
> usage(progname, 0);
> break;
> diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man
> index 1d65b5e0..d7884562 100644
> --- a/utils/exportd/exportd.man
> +++ b/utils/exportd/exportd.man
> @@ -51,6 +51,21 @@ spawns. The default is 1 thread, which is probably enough. More
> threads are usually only needed for NFS servers which need to handle
> mount storms of hundreds of NFS mounts in a few seconds, or when
> your DNS server is slow or unreliable.
> +.TP
> +.BR \-g " or " \-\-manage-gids
> +Accept requests from the kernel to map user id numbers into lists of
> +group id numbers for use in access control. An NFS request will
> +normally (except when using Kerberos or other cryptographic
> +authentication) contain a user-id and a list of group-ids. Due to a
> +limitation in the NFS protocol, at most 16 groups ids can be listed.
> +If you use the
> +.B \-g
> +flag, then the list of group ids received from the client will be
> +replaced by a list of group ids determined by an appropriate lookup on
> +the server. Note that the 'primary' group id is not affected so a
> +.B newgroup
> +command on the client will still be effective. This function requires
> +a Linux Kernel with version at least 2.6.21.
> .SH CONFIGURATION FILE
> Many of the options that can be set on the command line can also be
> controlled through values set in the
> @@ -63,6 +78,7 @@ configuration file.
> Values recognized in the
> .B [exportd]
> section include
> +.BR manage-gids ", and"
> .B debug
> which each have the same effect as the option with the same name.
> .SH FILES
>