import nfs-utils-2.5.4-25.el9

i9c-beta changed/i9c-beta/nfs-utils-2.5.4-25.el9
MSVSphere Packaging Team 8 months ago
parent a3d0b3874b
commit 8c4ceb6bfc

@ -0,0 +1,89 @@
commit c1c35487aba2cec828d9b8a1be9043000beadea5
Author: Lixiaokeng <lixiaokeng@huawei.com>
Date: Mon Oct 24 13:00:50 2022 -0400
blkmapd: fix coredump in bl_add_disk
The serial->data is not malloced separately (just part of
the serial), so it can't be freed. The bl_serial has its
own free function. Use it.
Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
diff --git a/utils/blkmapd/device-discovery.c b/utils/blkmapd/device-discovery.c
index 49935c2e..bd890598 100644
--- a/utils/blkmapd/device-discovery.c
+++ b/utils/blkmapd/device-discovery.c
@@ -187,10 +187,7 @@ static void bl_add_disk(char *filepath)
}
if (disk && diskpath) {
- if (serial) {
- free(serial->data);
- free(serial);
- }
+ bl_free_scsi_string(serial);
return;
}
@@ -228,10 +225,7 @@ static void bl_add_disk(char *filepath)
disk->size = size;
disk->valid_path = path;
}
- if (serial) {
- free(serial->data);
- free(serial);
- }
+ bl_free_scsi_string(serial);
}
return;
@@ -241,10 +235,7 @@ static void bl_add_disk(char *filepath)
free(path->full_path);
free(path);
}
- if (serial) {
- free(serial->data);
- free(serial);
- }
+ bl_free_scsi_string(serial);
return;
}
diff --git a/utils/blkmapd/device-discovery.h b/utils/blkmapd/device-discovery.h
index a86eed99..462aa943 100644
--- a/utils/blkmapd/device-discovery.h
+++ b/utils/blkmapd/device-discovery.h
@@ -151,6 +151,8 @@ uint64_t process_deviceinfo(const char *dev_addr_buf,
extern ssize_t atomicio(ssize_t(*f) (int, void *, size_t),
int fd, void *_s, size_t n);
+extern struct bl_serial *bl_create_scsi_string(int len, const char *bytes);
+extern void bl_free_scsi_string(struct bl_serial *str);
extern struct bl_serial *bldev_read_serial(int fd, const char *filename);
extern enum bl_path_state_e bldev_read_ap_state(int fd);
extern int bl_discover_devices(void);
diff --git a/utils/blkmapd/device-inq.c b/utils/blkmapd/device-inq.c
index c7952c3e..9e5749ef 100644
--- a/utils/blkmapd/device-inq.c
+++ b/utils/blkmapd/device-inq.c
@@ -53,7 +53,7 @@
#define DEF_ALLOC_LEN 255
#define MX_ALLOC_LEN (0xc000 + 0x80)
-static struct bl_serial *bl_create_scsi_string(int len, const char *bytes)
+struct bl_serial *bl_create_scsi_string(int len, const char *bytes)
{
struct bl_serial *s;
@@ -66,7 +66,7 @@ static struct bl_serial *bl_create_scsi_string(int len, const char *bytes)
return s;
}
-static void bl_free_scsi_string(struct bl_serial *str)
+void bl_free_scsi_string(struct bl_serial *str)
{
if (str)
free(str);

@ -0,0 +1,199 @@
diff --git a/support/export/v4root.c b/support/export/v4root.c
index c12a7d85..826cc219 100644
--- a/support/export/v4root.c
+++ b/support/export/v4root.c
@@ -135,7 +135,7 @@ v4root_support(void)
if (!warned) {
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.");
+ xlog(L_WARNING, "is specified in /etc/exports file.");
warned++;
}
return 0;
diff --git a/systemd/nfs-blkmap.service b/systemd/nfs-blkmap.service
index 6aa45ba1..57181632 100644
--- a/systemd/nfs-blkmap.service
+++ b/systemd/nfs-blkmap.service
@@ -1,5 +1,6 @@
[Unit]
Description=pNFS block layout mapping daemon
+Documentation=man:blkmapd(8)
DefaultDependencies=no
Conflicts=umount.target
After=rpc_pipefs.target
diff --git a/systemd/nfs-idmapd.service b/systemd/nfs-idmapd.service
index f38fe527..bf6f4ded 100644
--- a/systemd/nfs-idmapd.service
+++ b/systemd/nfs-idmapd.service
@@ -1,5 +1,6 @@
[Unit]
Description=NFSv4 ID-name mapping service
+Documentation=man:idmapd(8)
DefaultDependencies=no
Requires=rpc_pipefs.target
After=rpc_pipefs.target local-fs.target
diff --git a/systemd/nfs-mountd.service b/systemd/nfs-mountd.service
index e8ece533..4618fab1 100644
--- a/systemd/nfs-mountd.service
+++ b/systemd/nfs-mountd.service
@@ -1,5 +1,6 @@
[Unit]
Description=NFS Mount Daemon
+Documentation=man:rpc.mountd(8)
DefaultDependencies=no
Requires=proc-fs-nfsd.mount
Wants=network-online.target
diff --git a/systemd/nfs-server.service b/systemd/nfs-server.service
index 41479169..58bc0917 100644
--- a/systemd/nfs-server.service
+++ b/systemd/nfs-server.service
@@ -1,5 +1,6 @@
[Unit]
Description=NFS server and services
+Documentation=man:rpc.nfsd(8) man:exportfs(8)
DefaultDependencies=no
Requires=network.target proc-fs-nfsd.mount
Requires=nfs-mountd.service
diff --git a/systemd/nfsdcld.service b/systemd/nfsdcld.service
index a32d2430..3ced5658 100644
--- a/systemd/nfsdcld.service
+++ b/systemd/nfsdcld.service
@@ -1,5 +1,6 @@
[Unit]
Description=NFSv4 Client Tracking Daemon
+Documentation=man:nfsdcld(8)
DefaultDependencies=no
Conflicts=umount.target
Requires=rpc_pipefs.target proc-fs-nfsd.mount
diff --git a/systemd/rpc-gssd.service.in b/systemd/rpc-gssd.service.in
index 6807db35..38382ed3 100644
--- a/systemd/rpc-gssd.service.in
+++ b/systemd/rpc-gssd.service.in
@@ -1,5 +1,6 @@
[Unit]
Description=RPC security service for NFS client and server
+Documentation=man:rpc.gssd(8)
DefaultDependencies=no
Conflicts=umount.target
Requires=rpc_pipefs.target
diff --git a/systemd/rpc-statd-notify.service b/systemd/rpc-statd-notify.service
index aad4c0d2..962f18b2 100644
--- a/systemd/rpc-statd-notify.service
+++ b/systemd/rpc-statd-notify.service
@@ -1,5 +1,6 @@
[Unit]
Description=Notify NFS peers of a restart
+Documentation=man:sm-notify(8) man:rpc.statd(8)
DefaultDependencies=no
Wants=network-online.target
After=local-fs.target network-online.target nss-lookup.target
diff --git a/systemd/rpc-statd.service b/systemd/rpc-statd.service
index 392750da..660ed861 100644
--- a/systemd/rpc-statd.service
+++ b/systemd/rpc-statd.service
@@ -1,5 +1,6 @@
[Unit]
Description=NFS status monitor for NFSv2/3 locking.
+Documentation=man:rpc.statd(8)
DefaultDependencies=no
Conflicts=umount.target
Requires=nss-lookup.target rpcbind.socket
diff --git a/systemd/rpc-svcgssd.service b/systemd/rpc-svcgssd.service
index cb2bcd4f..401fba11 100644
--- a/systemd/rpc-svcgssd.service
+++ b/systemd/rpc-svcgssd.service
@@ -1,5 +1,6 @@
[Unit]
Description=RPC security service for NFS server
+Documentation=man:rpc.svcgssd(8)
DefaultDependencies=no
After=local-fs.target
PartOf=nfs-server.service
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
index 83dd6807..e5fb10f5 100644
--- a/utils/exportfs/exports.man
+++ b/utils/exportfs/exports.man
@@ -298,7 +298,7 @@ set.
The
.I nocrossmnt
-option can explictly disable
+option can explicitly disable
.I crossmnt
if it was previously set. This is rarely useful.
.TP
diff --git a/utils/mount/mount_libmount.c b/utils/mount/mount_libmount.c
index aa4ac5c3..fd6cb2cb 100644
--- a/utils/mount/mount_libmount.c
+++ b/utils/mount/mount_libmount.c
@@ -442,7 +442,7 @@ int main(int argc, char *argv[])
mnt_init_debug(0);
cxt = mnt_new_context();
if (!cxt) {
- nfs_error(_("Can't initilize libmount: %s"),
+ nfs_error(_("Can't initialize libmount: %s"),
strerror(errno));
rc = EX_FAIL;
goto done;
diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
index dfc31a5d..fe1ad354 100644
--- a/utils/mount/nfs.man
+++ b/utils/mount/nfs.man
@@ -967,7 +967,7 @@ Some server features misbehave in the face of a migration-compatible
identification string.
The
.B nomigration
-option retains the use of a traditional client indentification string
+option retains the use of a traditional client identification string
which is compatible with legacy NFS servers.
This is also the behavior if neither option is specified.
A client's open and lock state cannot be migrated transparently
@@ -1810,7 +1810,7 @@ auxiliary services such as the NLM service can choose
any unused port number at random.
.P
Common firewall configurations block the well-known rpcbind port.
-In the absense of an rpcbind service,
+In the absence of an rpcbind service,
the server administrator fixes the port number
of NFS-related services so that the firewall
can allow access to specific NFS service ports.
diff --git a/utils/mount/nfsmount.conf.man b/utils/mount/nfsmount.conf.man
index 73c3e118..7d4a33c9 100644
--- a/utils/mount/nfsmount.conf.man
+++ b/utils/mount/nfsmount.conf.man
@@ -43,7 +43,7 @@ and will be shifted to lower case before being passed to the filesystem.
.PP
Boolean mount options which do not need an equals sign must be given as
.RI \[dq] option =True".
-Instead of preceeding such an option with
+Instead of preceding such an option with
.RB \[dq] no \[dq]
its negation must be given as
.RI \[dq] option =False".
diff --git a/utils/nfsdcld/nfsdcld.man b/utils/nfsdcld/nfsdcld.man
index 861f1c49..ee6e9dcf 100644
--- a/utils/nfsdcld/nfsdcld.man
+++ b/utils/nfsdcld/nfsdcld.man
@@ -198,7 +198,7 @@ initialize client tracking in the following order: First, the \fBnfsdcld\fR upc
the \fBnfsdcltrack\fR usermodehelper upcall. Finally, the legacy client tracking.
.PP
This daemon should be run as root, as the pipe that it uses to communicate
-with the kernel is only accessable by root. The daemon however does drop all
+with the kernel is only accessible by root. The daemon however does drop all
superuser capabilities after starting. Because of this, the \fIstoragedir\fR
should be owned by root, and be readable and writable by owner.
.PP
diff --git a/utils/nfsdcltrack/nfsdcltrack.man b/utils/nfsdcltrack/nfsdcltrack.man
index cc24b7a2..3905ba46 100644
--- a/utils/nfsdcltrack/nfsdcltrack.man
+++ b/utils/nfsdcltrack/nfsdcltrack.man
@@ -80,7 +80,7 @@ section. For example:
.br
storagedir = /shared/nfs/nfsdcltrack
.in -5
-Debuging to syslog can also be enabled by setting "debug = 1" in this file.
+Debugging to syslog can also be enabled by setting "debug = 1" in this file.
.SH "LEGACY TRANSITION MECHANISM"
.IX Header "LEGACY TRANSITION MECHANISM"
The Linux kernel NFSv4 server has historically tracked this information

@ -0,0 +1,239 @@
diff --git a/aclocal/libtirpc.m4 b/aclocal/libtirpc.m4
index 27368ff2..4379b14d 100644
--- a/aclocal/libtirpc.m4
+++ b/aclocal/libtirpc.m4
@@ -26,6 +26,11 @@ AC_DEFUN([AC_LIBTIRPC], [
[Define to 1 if your tirpc library provides libtirpc_set_debug])],,
[${LIBS}])])
+ AS_IF([test -n "${LIBTIRPC}"],
+ [AC_CHECK_LIB([tirpc], [rpc_gss_seccreate],
+ [AC_DEFINE([HAVE_TIRPC_GSS_SECCREATE], [1],
+ [Define to 1 if your tirpc library provides rpc_gss_seccreate])],,
+ [${LIBS}])])
AC_SUBST([AM_CPPFLAGS])
AC_SUBST(LIBTIRPC)
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index ae568f15..7629de0b 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -70,6 +70,9 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <syscall.h>
+#ifdef HAVE_TIRPC_GSS_SECCREATE
+#include <rpc/rpcsec_gss.h>
+#endif
#include "gssd.h"
#include "err_util.h"
@@ -330,6 +333,11 @@ create_auth_rpc_client(struct clnt_info *clp,
struct timeval timeout;
struct sockaddr *addr = (struct sockaddr *) &clp->addr;
socklen_t salen;
+#ifdef HAVE_TIRPC_GSS_SECCREATE
+ rpc_gss_options_req_t req;
+ rpc_gss_options_ret_t ret;
+ char mechanism[] = "kerberos_v5";
+#endif
pthread_t tid = pthread_self();
sec.qop = GSS_C_QOP_DEFAULT;
@@ -410,15 +418,43 @@ create_auth_rpc_client(struct clnt_info *clp,
printerr(3, "create_auth_rpc_client(0x%lx): creating context with server %s\n",
tid, tgtname);
+#ifdef HAVE_TIRPC_GSS_SECCREATE
+ memset(&req, 0, sizeof(req));
+ req.my_cred = sec.cred;
+ auth = rpc_gss_seccreate(rpc_clnt, tgtname, mechanism,
+ rpcsec_gss_svc_none, NULL, &req, &ret);
+#else
auth = authgss_create_default(rpc_clnt, tgtname, &sec);
+#endif
if (!auth) {
+#ifdef HAVE_TIRPC_GSS_SECCREATE
+ if (ret.minor_status == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ printerr(2, "WARNING: server=%s failed context "
+ "creation with KRB5_AP_ERR_BAD_INTEGRITY\n",
+ clp->servername);
+ if (cred == GSS_C_NO_CREDENTIAL)
+ retval = gssd_refresh_krb5_machine_credential(clp->servername,
+ "*", NULL, 1);
+ else
+ retval = gssd_k5_remove_bad_service_cred(clp->servername);
+ if (!retval) {
+ auth = rpc_gss_seccreate(rpc_clnt, tgtname,
+ mechanism, rpcsec_gss_svc_none,
+ NULL, &req, &ret);
+ if (auth)
+ goto success;
+ }
+ }
+#endif
/* Our caller should print appropriate message */
printerr(2, "WARNING: Failed to create krb5 context for "
"user with uid %d for server %s\n",
uid, tgtname);
goto out_fail;
}
-
+#ifdef HAVE_TIRPC_GSS_SECCREATE
+success:
+#endif
/* Success !!! */
rpc_clnt->cl_auth = auth;
*clnt_return = rpc_clnt;
@@ -571,7 +607,7 @@ krb5_use_machine_creds(struct clnt_info *clp, uid_t uid,
do {
gssd_refresh_krb5_machine_credential(clp->servername,
- service, srchost);
+ service, srchost, 0);
/*
* Get a list of credential cache names and try each
* of them until one works or we've tried them all
diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
index e3f270e9..6f66ef4f 100644
--- a/utils/gssd/krb5_util.c
+++ b/utils/gssd/krb5_util.c
@@ -165,7 +165,7 @@ static int select_krb5_ccache(const struct dirent *d);
static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
const char **cctype, struct dirent **d);
static int gssd_get_single_krb5_cred(krb5_context context,
- krb5_keytab kt, struct gssd_k5_kt_princ *ple);
+ krb5_keytab kt, struct gssd_k5_kt_princ *ple, int force_renew);
static int query_krb5_ccache(const char* cred_cache, char **ret_princname,
char **ret_realm);
@@ -391,7 +391,8 @@ gssd_check_if_cc_exists(struct gssd_k5_kt_princ *ple)
static int
gssd_get_single_krb5_cred(krb5_context context,
krb5_keytab kt,
- struct gssd_k5_kt_princ *ple)
+ struct gssd_k5_kt_princ *ple,
+ int force_renew)
{
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS
krb5_get_init_creds_opt *init_opts = NULL;
@@ -421,7 +422,7 @@ gssd_get_single_krb5_cred(krb5_context context,
*/
now += 300;
pthread_mutex_lock(&ple_lock);
- if (ple->ccname && ple->endtime > now && !nocache) {
+ if (ple->ccname && ple->endtime > now && !nocache && !force_renew) {
printerr(3, "%s(0x%lx): Credentials in CC '%s' are good until %s",
__func__, tid, ple->ccname, ctime((time_t *)&ple->endtime));
code = 0;
@@ -1155,7 +1156,8 @@ err_cache:
static int
gssd_refresh_krb5_machine_credential_internal(char *hostname,
struct gssd_k5_kt_princ *ple,
- char *service, char *srchost)
+ char *service, char *srchost,
+ int force_renew)
{
krb5_error_code code = 0;
krb5_context context;
@@ -1221,7 +1223,7 @@ gssd_refresh_krb5_machine_credential_internal(char *hostname,
goto out_free_kt;
}
}
- retval = gssd_get_single_krb5_cred(context, kt, ple);
+ retval = gssd_get_single_krb5_cred(context, kt, ple, force_renew);
out_free_kt:
krb5_kt_close(context, kt);
out_free_context:
@@ -1344,7 +1346,7 @@ gssd_get_krb5_machine_cred_list(char ***list)
pthread_mutex_unlock(&ple_lock);
/* Make sure cred is up-to-date before returning it */
retval = gssd_refresh_krb5_machine_credential_internal(NULL, ple,
- NULL, NULL);
+ NULL, NULL, 0);
pthread_mutex_lock(&ple_lock);
if (gssd_k5_kt_princ_list == NULL) {
/* Looks like we did shutdown... abort */
@@ -1456,10 +1458,12 @@ gssd_destroy_krb5_principals(int destroy_machine_creds)
*/
int
gssd_refresh_krb5_machine_credential(char *hostname,
- char *service, char *srchost)
+ char *service, char *srchost,
+ int force_renew)
{
return gssd_refresh_krb5_machine_credential_internal(hostname, NULL,
- service, srchost);
+ service, srchost,
+ force_renew);
}
/*
@@ -1549,6 +1553,48 @@ gssd_acquire_user_cred(gss_cred_id_t *gss_cred)
return ret;
}
+/* Removed a service ticket for nfs/<name> from the ticket cache
+ */
+int
+gssd_k5_remove_bad_service_cred(char *name)
+{
+ krb5_creds in_creds, out_creds;
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache cache;
+ krb5_principal principal;
+ int retflags = KRB5_TC_MATCH_SRV_NAMEONLY;
+ char srvname[1024];
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ goto out_cred;
+ ret = krb5_cc_default(context, &cache);
+ if (ret)
+ goto out_free_context;
+ ret = krb5_cc_get_principal(context, cache, &principal);
+ if (ret)
+ goto out_close_cache;
+ memset(&in_creds, 0, sizeof(in_creds));
+ in_creds.client = principal;
+ sprintf(srvname, "nfs/%s", name);
+ ret = krb5_parse_name(context, srvname, &in_creds.server);
+ if (ret)
+ goto out_free_principal;
+ ret = krb5_cc_retrieve_cred(context, cache, retflags, &in_creds, &out_creds);
+ if (ret)
+ goto out_free_principal;
+ ret = krb5_cc_remove_cred(context, cache, 0, &out_creds);
+out_free_principal:
+ krb5_free_principal(context, principal);
+out_close_cache:
+ krb5_cc_close(context, cache);
+out_free_context:
+ krb5_free_context(context);
+out_cred:
+ return ret;
+}
+
#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
/*
* this routine obtains a credentials handle via gss_acquire_cred()
diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h
index 2415205a..7ef87018 100644
--- a/utils/gssd/krb5_util.h
+++ b/utils/gssd/krb5_util.h
@@ -16,11 +16,13 @@ int gssd_get_krb5_machine_cred_list(char ***list);
void gssd_free_krb5_machine_cred_list(char **list);
void gssd_destroy_krb5_principals(int destroy_machine_creds);
int gssd_refresh_krb5_machine_credential(char *hostname,
- char *service, char *srchost);
+ char *service, char *srchost,
+ int force_renew);
char *gssd_k5_err_msg(krb5_context context, krb5_error_code code);
void gssd_k5_get_default_realm(char **def_realm);
int gssd_acquire_user_cred(gss_cred_id_t *gss_cred);
+int gssd_k5_remove_bad_service_cred(char *srvname);
#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
extern int limit_to_legacy_enctypes;

@ -0,0 +1,110 @@
commit 75b04a9bff709a49f55326b439851822dd630be6
Author: Olga Kornievskaia <kolga@netapp.com>
Date: Mon Oct 16 11:45:54 2023 -0400
gssd: fix handling DNS lookup failure
When the kernel does its first ever lookup for a given server ip it
sends down info for server, protocol, etc. On the gssd side as it
scans the pipefs structure and sees a new entry it reads that info
and creates a clp_info structure. At that time it also does
a DNS lookup of the provided ip to name using getnameinfo(),
this is saved in clp->servername for all other upcalls that is
down under that directory.
If this 1st getnameinfo() results in a failed resolution for
whatever reason (a temporary DNS resolution problem), this cause
of all other future upcalls to fail.
As a fix, this patch proposed to (1) save the server info that's
passed only in the initial pipefs new entry creation in the
clp_info structure, then (2) for the upcalls, if clp->servername
is NULL, then do the DNS lookup again and set all the needed
clp_info fields upon successful resolution.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
index 833d8e0..ca9b326 100644
--- a/utils/gssd/gssd.c
+++ b/utils/gssd/gssd.c
@@ -365,6 +365,12 @@ gssd_read_service_info(int dirfd, struct clnt_info *clp)
fail:
printerr(0, "ERROR: failed to parse %s/info\n", clp->relpath);
+ clp->upcall_address = strdup(address);
+ clp->upcall_port = strdup(port);
+ clp->upcall_program = program;
+ clp->upcall_vers = version;
+ clp->upcall_protoname = strdup(protoname);
+ clp->upcall_service = strdup(service);
free(servername);
free(protoname);
clp->servicename = NULL;
@@ -408,6 +414,16 @@ gssd_free_client(struct clnt_info *clp)
free(clp->servicename);
free(clp->servername);
free(clp->protocol);
+ if (!clp->servername) {
+ if (clp->upcall_address)
+ free(clp->upcall_address);
+ if (clp->upcall_port)
+ free(clp->upcall_port);
+ if (clp->upcall_protoname)
+ free(clp->upcall_protoname);
+ if (clp->upcall_service)
+ free(clp->upcall_service);
+ }
free(clp);
}
@@ -446,6 +462,31 @@ gssd_clnt_gssd_cb(int UNUSED(fd), short UNUSED(which), void *data)
{
struct clnt_info *clp = data;
+ /* if there was a failure to translate IP to name for this server,
+ * try again
+ */
+ if (!clp->servername) {
+ if (!gssd_addrstr_to_sockaddr((struct sockaddr *)&clp->addr,
+ clp->upcall_address, clp->upcall_port ?
+ clp->upcall_port : "")) {
+ goto do_upcall;
+ }
+ clp->servername = gssd_get_servername(clp->upcall_address,
+ (struct sockaddr *)&clp->addr, clp->upcall_address);
+ if (!clp->servername)
+ goto do_upcall;
+
+ if (asprintf(&clp->servicename, "%s@%s", clp->upcall_service,
+ clp->servername) < 0) {
+ free(clp->servername);
+ clp->servername = NULL;
+ goto do_upcall;
+ }
+ clp->prog = clp->upcall_program;
+ clp->vers = clp->upcall_vers;
+ clp->protocol = strdup(clp->upcall_protoname);
+ }
+do_upcall:
handle_gssd_upcall(clp);
}
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
index 519dc43..4e070ed 100644
--- a/utils/gssd/gssd.h
+++ b/utils/gssd/gssd.h
@@ -86,6 +86,12 @@ struct clnt_info {
int gssd_fd;
struct event *gssd_ev;
struct sockaddr_storage addr;
+ char *upcall_address;
+ char *upcall_port;
+ int upcall_program;
+ int upcall_vers;
+ char *upcall_protoname;
+ char *upcall_service;
};
struct clnt_upcall_info {

@ -0,0 +1,30 @@
commit 608591ddf1ee59c4dda82ceca3f27c90486c5618
Author: Yongcheng Yang <yongcheng.yang@gmail.com>
Date: Wed Apr 5 12:11:53 2023 -0400
nfsmount.conf: Fix typo of the attribute name
Signed-off-by: Yongcheng Yang <yongcheng.yang@gmail.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
diff --git a/utils/mount/nfsmount.conf b/utils/mount/nfsmount.conf
index 342063f..c498eb8 100644
--- a/utils/mount/nfsmount.conf
+++ b/utils/mount/nfsmount.conf
@@ -59,13 +59,13 @@
# acregmin=30
#
# The Maximum time (in seconds) file attributes are cached
-# acregmin=60
+# acregmax=60
#
# The minimum time (in seconds) directory attributes are cached
-# acregmin=30
+# acdirmin=30
#
# The Maximum time (in seconds) directory attributes are cached
-# acregmin=60
+# acdirmax=60
#
# Enable Access Control Lists
# Acl=False

@ -0,0 +1,24 @@
commit a746c35822e557766d1871ec976490a71e6962d9
Author: Zhi Li <yieli@redhat.com>
Date: Wed Apr 5 12:08:10 2023 -0400
rpcdebug: avoid buffer underflow if read() returns 0
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2176740
Signed-off-by: Zhi Li <yieli@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
diff --git a/tools/rpcdebug/rpcdebug.c b/tools/rpcdebug/rpcdebug.c
index 68206cc5..ec05179e 100644
--- a/tools/rpcdebug/rpcdebug.c
+++ b/tools/rpcdebug/rpcdebug.c
@@ -257,7 +257,7 @@ get_flags(char *module)
perror(filename);
exit(1);
}
- if ((len = read(sysfd, buffer, sizeof(buffer))) < 0) {
+ if ((len = read(sysfd, buffer, sizeof(buffer))) <= 0) {
perror("read");
exit(1);
}

@ -0,0 +1,427 @@
diff --git a/support/export/cache.c b/support/export/cache.c
index a5823e92..396b3b73 100644
--- a/support/export/cache.c
+++ b/support/export/cache.c
@@ -932,6 +932,7 @@ static void write_fsloc(char **bp, int *blen, struct exportent *ep)
release_replicas(servers);
}
#endif
+
static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask)
{
struct sec_entry *p;
@@ -949,7 +950,20 @@ static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_m
qword_addint(bp, blen, p->flav->fnum);
qword_addint(bp, blen, p->flags & flag_mask);
}
+}
+
+static void write_xprtsec(char **bp, int *blen, struct exportent *ep)
+{
+ struct xprtsec_entry *p;
+
+ for (p = ep->e_xprtsec; p->info; p++);
+ if (p == ep->e_xprtsec)
+ return;
+ qword_add(bp, blen, "xprtsec");
+ qword_addint(bp, blen, p - ep->e_xprtsec);
+ for (p = ep->e_xprtsec; p->info; p++)
+ qword_addint(bp, blen, p->info->number);
}
static int dump_to_cache(int f, char *buf, int blen, char *domain,
@@ -992,6 +1006,7 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain,
qword_add(&bp, &blen, "uuid");
qword_addhex(&bp, &blen, u, 16);
}
+ write_xprtsec(&bp, &blen, exp);
xlog(D_AUTH, "granted access to %s for %s",
path, *domain == '$' ? domain+1 : domain);
} else {
diff --git a/support/include/nfs/export.h b/support/include/nfs/export.h
index 0eca828e..be5867cf 100644
--- a/support/include/nfs/export.h
+++ b/support/include/nfs/export.h
@@ -40,4 +40,18 @@
#define NFSEXP_OLD_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \
| NFSEXP_ALLSQUASH)
+/*
+ * Transport layer security policies that are permitted to access
+ * an export
+ */
+#define NFSEXP_XPRTSEC_NONE 0x0001
+#define NFSEXP_XPRTSEC_TLS 0x0002
+#define NFSEXP_XPRTSEC_MTLS 0x0004
+
+#define NFSEXP_XPRTSEC_NUM (3)
+
+#define NFSEXP_XPRTSEC_ALL (NFSEXP_XPRTSEC_NONE | \
+ NFSEXP_XPRTSEC_TLS | \
+ NFSEXP_XPRTSEC_MTLS)
+
#endif /* _NSF_EXPORT_H */
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index 6faba71b..61c19933 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -62,6 +62,18 @@ struct sec_entry {
int flags;
};
+#define XPRTSECMODE_COUNT 3
+
+struct xprtsec_info {
+ const char *name;
+ int number;
+};
+
+struct xprtsec_entry {
+ const struct xprtsec_info *info;
+ int flags;
+};
+
/*
* Data related to a single exports entry as returned by getexportent.
* FIXME: export options should probably be parsed at a later time to
@@ -83,6 +95,7 @@ struct exportent {
char * e_fslocdata;
char * e_uuid;
struct sec_entry e_secinfo[SECFLAVOR_COUNT+1];
+ struct xprtsec_entry e_xprtsec[XPRTSECMODE_COUNT + 1];
unsigned int e_ttl;
char * e_realpath;
};
@@ -99,6 +112,7 @@ struct rmtabent {
void setexportent(char *fname, char *type);
struct exportent * getexportent(int,int);
void secinfo_show(FILE *fp, struct exportent *ep);
+void xprtsecinfo_show(FILE *fp, struct exportent *ep);
void putexportent(struct exportent *xep);
void endexportent(void);
struct exportent * mkexportent(char *hname, char *path, char *opts);
diff --git a/support/nfs/exports.c b/support/nfs/exports.c
index ec6f8013..d36f7664 100644
--- a/support/nfs/exports.c
+++ b/support/nfs/exports.c
@@ -99,6 +99,7 @@ static void init_exportent (struct exportent *ee, int fromkernel)
ee->e_fslocmethod = FSLOC_NONE;
ee->e_fslocdata = NULL;
ee->e_secinfo[0].flav = NULL;
+ ee->e_xprtsec[0].info = NULL;
ee->e_nsquids = 0;
ee->e_nsqgids = 0;
ee->e_uuid = NULL;
@@ -122,7 +123,7 @@ getexportent(int fromkernel, int fromexports)
if (first || (ok = getexport(exp, sizeof(exp))) == 0) {
has_default_opts = 0;
has_default_subtree_opts = 0;
-
+
init_exportent(&def_ee, fromkernel);
ok = getpath(def_ee.e_path, sizeof(def_ee.e_path));
@@ -146,7 +147,7 @@ getexportent(int fromkernel, int fromexports)
if (exp[0] == '-' && !fromkernel) {
if (parseopts(exp + 1, &def_ee, 0, &has_default_subtree_opts) < 0)
return NULL;
-
+
has_default_opts = 1;
ok = getexport(exp, sizeof(exp));
@@ -239,7 +240,6 @@ void secinfo_show(FILE *fp, struct exportent *ep)
if (ep->e_secinfo[0].flav == NULL)
secinfo_addflavor(find_flavor("sys"), ep);
for (p1=ep->e_secinfo; p1->flav; p1=p2) {
-
fprintf(fp, ",sec=%s", p1->flav->flavour);
for (p2=p1+1; (p2->flav != NULL) && (p1->flags == p2->flags);
p2++) {
@@ -249,6 +249,17 @@ void secinfo_show(FILE *fp, struct exportent *ep)
}
}
+void xprtsecinfo_show(FILE *fp, struct exportent *ep)
+{
+ struct xprtsec_entry *p1, *p2;
+
+ for (p1 = ep->e_xprtsec; p1->info; p1 = p2) {
+ fprintf(fp, ",xprtsec=%s", p1->info->name);
+ for (p2 = p1 + 1; p2->info && (p1->flags == p2->flags); p2++)
+ fprintf(fp, ":%s", p2->info->name);
+ }
+}
+
static void
fprintpath(FILE *fp, const char *path)
{
@@ -345,6 +356,7 @@ putexportent(struct exportent *ep)
}
fprintf(fp, "anonuid=%d,anongid=%d", ep->e_anonuid, ep->e_anongid);
secinfo_show(fp, ep);
+ xprtsecinfo_show(fp, ep);
fprintf(fp, ")\n");
}
@@ -483,6 +495,75 @@ static unsigned int parse_flavors(char *str, struct exportent *ep)
return out;
}
+static const struct xprtsec_info xprtsec_name2info[] = {
+ { "none", NFSEXP_XPRTSEC_NONE },
+ { "tls", NFSEXP_XPRTSEC_TLS },
+ { "mtls", NFSEXP_XPRTSEC_MTLS },
+ { NULL, 0 }
+};
+
+static const struct xprtsec_info *find_xprtsec_info(const char *name)
+{
+ const struct xprtsec_info *info;
+
+ for (info = xprtsec_name2info; info->name; info++)
+ if (strcmp(info->name, name) == 0)
+ return info;
+ return NULL;
+}
+
+/*
+ * Append the given xprtsec mode to the exportent's e_xprtsec array,
+ * or do nothing if it's already there. Returns the index of flavor in
+ * the resulting array in any case.
+ */
+static int xprtsec_addmode(const struct xprtsec_info *info, struct exportent *ep)
+{
+ struct xprtsec_entry *p;
+
+ for (p = ep->e_xprtsec; p->info; p++)
+ if (p->info == info || p->info->number == info->number)
+ return p - ep->e_xprtsec;
+
+ if (p - ep->e_xprtsec >= XPRTSECMODE_COUNT) {
+ xlog(L_ERROR, "more than %d xprtsec modes on an export\n",
+ XPRTSECMODE_COUNT);
+ return -1;
+ }
+ p->info = info;
+ p->flags = ep->e_flags;
+ (p + 1)->info = NULL;
+ return p - ep->e_xprtsec;
+}
+
+/*
+ * @str is a colon seperated list of transport layer security modes.
+ * Their order is recorded in @ep, and a bitmap corresponding to the
+ * list is returned.
+ *
+ * A zero return indicates an error.
+ */
+static unsigned int parse_xprtsec(char *str, struct exportent *ep)
+{
+ unsigned int out = 0;
+ char *name;
+
+ while ((name = strsep(&str, ":"))) {
+ const struct xprtsec_info *info = find_xprtsec_info(name);
+ int bit;
+
+ if (!info) {
+ xlog(L_ERROR, "unknown xprtsec mode %s\n", name);
+ return 0;
+ }
+ bit = xprtsec_addmode(info, 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)
{
@@ -621,7 +702,7 @@ parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr)
ep->e_anonuid = strtol(opt+8, &oe, 10);
if (opt[8]=='\0' || *oe != '\0') {
xlog(L_ERROR, "%s: %d: bad anonuid \"%s\"\n",
- flname, flline, opt);
+ flname, flline, opt);
bad_option:
free(opt);
return -1;
@@ -631,7 +712,7 @@ bad_option:
ep->e_anongid = strtol(opt+8, &oe, 10);
if (opt[8]=='\0' || *oe != '\0') {
xlog(L_ERROR, "%s: %d: bad anongid \"%s\"\n",
- flname, flline, opt);
+ flname, flline, opt);
goto bad_option;
}
} else if (strncmp(opt, "squash_uids=", 12) == 0) {
@@ -649,13 +730,13 @@ bad_option:
setflags(NFSEXP_FSID, active, ep);
} else {
ep->e_fsid = strtoul(opt+5, &oe, 0);
- if (opt[5]!='\0' && *oe == '\0')
+ if (opt[5]!='\0' && *oe == '\0')
setflags(NFSEXP_FSID, active, ep);
else if (valid_uuid(opt+5))
ep->e_uuid = strdup(opt+5);
else {
xlog(L_ERROR, "%s: %d: bad fsid \"%s\"\n",
- flname, flline, opt);
+ flname, flline, opt);
goto bad_option;
}
}
@@ -688,6 +769,9 @@ bad_option:
active = parse_flavors(opt+4, ep);
if (!active)
goto bad_option;
+ } else if (strncmp(opt, "xprtsec=", 8) == 0) {
+ if (!parse_xprtsec(opt + 8, ep))
+ goto bad_option;
} else {
xlog(L_ERROR, "%s:%d: unknown keyword \"%s\"\n",
flname, flline, opt);
@@ -709,7 +793,7 @@ out:
if (warn && !had_subtree_opt)
xlog(L_WARNING, "%s [%d]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"%s:%s\".\n"
" Assuming default behaviour ('no_subtree_check').\n"
- " NOTE: this default has changed since nfs-utils version 1.0.x\n",
+ " NOTE: this default has changed since nfs-utils version 1.0.x\n",
flname, flline,
ep->e_hostname, ep->e_path);
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 6ba615d1..a87a7806 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -743,6 +743,7 @@ dump(int verbose, int export_format)
#endif
}
secinfo_show(stdout, ep);
+ xprtsecinfo_show(stdout, ep);
printf("%c\n", (c != '(')? ')' : ' ');
}
}
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
index 54b3f877..83dd6807 100644
--- a/utils/exportfs/exports.man
+++ b/utils/exportfs/exports.man
@@ -125,7 +125,55 @@ In that case you may include multiple sec= options, and following options
will be enforced only for access using flavors listed in the immediately
preceding sec= option. The only options that are permitted to vary in
this way are ro, rw, no_root_squash, root_squash, and all_squash.
+.SS Transport layer security
+The Linux NFS server allows the use of RPC-with-TLS (RFC 9289) to
+protect RPC traffic between itself and its clients.
+Alternately, administrators can secure NFS traffic using a VPN,
+or an ssh tunnel or similar mechanism, in a way that is transparent
+to the server.
.PP
+To enable the use of RPC-with-TLS, the server's administrator must
+install and configure
+.BR tlshd
+to handle transport layer security handshake requests from the local
+kernel.
+Clients can then choose to use RPC-with-TLS or they may continue
+operating without it.
+.PP
+Administrators may require the use of RPC-with-TLS to protect access
+to individual exports.
+This is particularly useful when using non-cryptographic security
+flavors such as
+.IR sec=sys .
+The
+.I xprtsec=
+option, followed by an unordered colon-delimited list of security policies,
+can restrict access to the export to only clients that have negotiated
+transport-layer security.
+Currently supported transport layer security policies include:
+.TP
+.IR none
+The server permits clients to access the export
+without the use of transport layer security.
+.TP
+.IR tls
+The server permits clients that have negotiated an RPC-with-TLS session
+without peer authentication (confidentiality only) to access the export.
+Clients are not required to offer an x.509 certificate
+when establishing a transport layer security session.
+.TP
+.IR mtls
+The server permits clients that have negotiated an RPC-with-TLS session
+with peer authentication to access the export.
+The server requires clients to offer an x.509 certificate
+when establishing a transport layer security session.
+.PP
+If RPC-with-TLS is configured and enabled and the
+.I xprtsec=
+option is not specified, the default setting for an export is
+.IR xprtsec=none:tls:mtls .
+With this setting, the server permits clients to use any transport
+layer security mechanism or none at all to access the export.
.SS General Options
.BR exportfs
understands the following export options:
@@ -581,7 +629,8 @@ a character class wildcard match.
.BR netgroup (5),
.BR mountd (8),
.BR nfsd (8),
-.BR showmount (8).
+.BR showmount (8),
+.BR tlshd (8).
.\".SH DIAGNOSTICS
.\"An error parsing the file is reported using syslogd(8) as level NOTICE from
.\"a DAEMON whenever
diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
index d9f34df3..dfc31a5d 100644
--- a/utils/mount/nfs.man
+++ b/utils/mount/nfs.man
@@ -574,7 +574,43 @@ The
.B sloppy
option is an alternative to specifying
.BR mount.nfs " -s " option.
-
+.TP 1.5i
+.BI xprtsec= policy
+Specifies the use of transport layer security to protect NFS network
+traffic on behalf of this mount point.
+.I policy
+can be one of
+.BR none ,
+.BR tls ,
+or
+.BR mtls .
+.IP
+If
+.B none
+is specified,
+transport layer security is forced off, even if the NFS server supports
+transport layer security.
+If
+.B tls
+is specified, the client uses RPC-with-TLS to provide in-transit
+confidentiality.
+If
+.B mtls
+is specified, the client uses RPC-with-TLS to authenticate itself and
+to provide in-transit confidentiality.
+If either
+.B tls
+or
+.B mtls
+is specified and the server does not support RPC-with-TLS or peer
+authentication fails, the mount attempt fails.
+.IP
+If the
+.B xprtsec=
+option is not specified,
+the default behavior depends on the kernel version,
+but is usually equivalent to
+.BR "xprtsec=none" .
.SS "Options for NFS versions 2 and 3 only"
Use these options, along with the options in the above subsection,
for NFS versions 2 and 3 only.

@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
Name: nfs-utils
URL: http://linux-nfs.org/
Version: 2.5.4
Release: 20%{?dist}
Release: 25%{?dist}
Epoch: 1
# group all 32bit related archs
@ -48,6 +48,17 @@ Patch016: nfs-utils-2.5.4-covscan-return-value.patch
Patch017: nfs-utils-2.5.4-juncs-automount.patch
Patch018: nfs-utils-2.5.4-man-nfsconf.patch
#
# RHEL9.4
#
Patch019: nfs-utils-2.5.4-gssd-dns-failure.patch
Patch020: nfs-utils-2.5.4-gssd-bad-integ-error-support.patch
Patch021: nfs-utils-2.5.4-mount-mountconf-typo.patch
Patch022: nfs-utils-2.5.4-support-for-rpc-with-tls.patch
Patch023: nfs-utils-2.5.4-fix-typos-in-messages.patch
Patch024: nfs-utils-2.5.4-blkmapd-double-free.patch
Patch025: nfs-utils-2.5.4-rpcdebug-check-read-return.patch
Patch100: nfs-utils-1.2.1-statdpath-man.patch
Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch
Patch102: nfs-utils-1.2.5-idmap-errmsg.patch
@ -488,6 +499,25 @@ fi
%{_mandir}/*/nfsiostat.8.gz
%changelog
* Sun Feb 18 2024 Steve Dickson <steved@redhat.com> 2.5.4-25
- Update: Typos and documentation fixes (RHEL-22654)
* Fri Feb 16 2024 Pavel Reichl <preichl@redhat.com> - 2.5.4-24
- Fix gating (RHEL-25837)
* Tue Feb 6 2024 Steve Dickson <steved@redhat.com> 2.5.4-23
- Typos and documentation fixes (RHEL-22654)
- blkmapd: fix coredump in bl_add_disk (RHEL-7941)
- rpcdebug: avoid buffer underflow (RHEL-7931)
* Thu Feb 1 2024 Steve Dickson <steved@redhat.com> 2.5.4-22
- nfsmount.conf: Fix typo of the attribute name (RHEL-7904)
- Update to support for the NFS RPC-with-TLS (RHEL-14754)
* Thu Jan 11 2024 Steve Dickson <steved@redhat.com> 2.5.4-21
- gssd: fix handling DNS lookup failure (RHEL-15035)
- gssd: handle KRB5_AP_ERR_BAD_INTEGRITY errors (RHEL-15034)
* Mon Aug 7 2023 Steve Dickson <steved@redhat.com> 2.5.4-20
- Fixed a regression in the junction code (bz 2213669)

Loading…
Cancel
Save