git: 7a4f370a352f - stable/14 - nfs_commonsubs.c: Make all upper case user domain work

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Sun, 08 Dec 2024 01:43:15 UTC
The branch stable/14 has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=7a4f370a352f89f00411a0e9cd7a7b8f8424be3a

commit 7a4f370a352f89f00411a0e9cd7a7b8f8424be3a
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2024-11-24 20:47:56 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2024-12-08 01:41:52 +0000

    nfs_commonsubs.c: Make all upper case user domain work
    
    Without this patch, an all upper case user domain name
    (as specified by nfsuserd(8)) would not work.
    I believe this was done so that Kerberos realms were
    not confused with user domains.
    
    Now, RFC8881 specifies that the user domain name is a
    DNS name.  As such, all upper case names should work.
    
    This patch fixes this case so that it works.  The custom
    comparison function is no longer needed.
    
    PR:     282620
    
    (cherry picked from commit 0347ddf41f4226c0351d2d1d78f09e8300ebac93)
---
 sys/fs/nfs/nfs_commonsubs.c | 42 ++++++------------------------------------
 1 file changed, 6 insertions(+), 36 deletions(-)

diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index b83df5e21ecd..510e497bce2e 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -225,7 +225,6 @@ static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0,
 static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
 static void nfsv4_wanted(struct nfsv4lock *lp);
 static uint32_t nfsv4_filesavail(struct statfs *, struct mount *);
-static int nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len);
 static int nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name);
 static void nfsrv_removeuser(struct nfsusrgrp *usrp, int isuser);
 static int nfsrv_getrefstr(struct nfsrv_descript *, u_char **, u_char **,
@@ -3442,13 +3441,13 @@ tryagain:
 		/*
 		 * If an '@' is found and the domain name matches, search for
 		 * the name with dns stripped off.
-		 * Mixed case alpahbetics will match for the domain name, but
-		 * all upper case will not.
+		 * The match for alphabetics in now case insensitive,
+		 * since RFC8881 defines this string as a DNS domain name.
 		 */
 		if (cnt == 0 && i < len && i > 0 &&
 		    (len - 1 - i) == NFSD_VNET(nfsrv_dnsnamelen) &&
-		    !nfsrv_cmpmixedcase(cp,
-		     NFSD_VNET(nfsrv_dnsname), NFSD_VNET(nfsrv_dnsnamelen))) {
+		    strncasecmp(cp, NFSD_VNET(nfsrv_dnsname),
+		     NFSD_VNET(nfsrv_dnsnamelen)) == 0) {
 			len -= (NFSD_VNET(nfsrv_dnsnamelen) + 1);
 			*(cp - 1) = '\0';
 		}
@@ -3669,8 +3668,8 @@ tryagain:
 		 */
 		if (cnt == 0 && i < len && i > 0 &&
 		    (len - 1 - i) == NFSD_VNET(nfsrv_dnsnamelen) &&
-		    !nfsrv_cmpmixedcase(cp,
-		     NFSD_VNET(nfsrv_dnsname), NFSD_VNET(nfsrv_dnsnamelen))) {
+		    strncasecmp(cp, NFSD_VNET(nfsrv_dnsname),
+		    NFSD_VNET(nfsrv_dnsnamelen)) == 0) {
 			len -= (NFSD_VNET(nfsrv_dnsnamelen) + 1);
 			*(cp - 1) = '\0';
 		}
@@ -3718,35 +3717,6 @@ out:
 	return (error);
 }
 
-/*
- * Cmp len chars, allowing mixed case in the first argument to match lower
- * case in the second, but not if the first argument is all upper case.
- * Return 0 for a match, 1 otherwise.
- */
-static int
-nfsrv_cmpmixedcase(u_char *cp, u_char *cp2, int len)
-{
-	int i;
-	u_char tmp;
-	int fndlower = 0;
-
-	for (i = 0; i < len; i++) {
-		if (*cp >= 'A' && *cp <= 'Z') {
-			tmp = *cp++ + ('a' - 'A');
-		} else {
-			tmp = *cp++;
-			if (tmp >= 'a' && tmp <= 'z')
-				fndlower = 1;
-		}
-		if (tmp != *cp2++)
-			return (1);
-	}
-	if (fndlower)
-		return (0);
-	else
-		return (1);
-}
-
 /*
  * Set the port for the nfsuserd.
  */