[Bug 282620] NFSv4 user mapping not working

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 08 Nov 2024 02:53:59 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=282620

            Bug ID: 282620
           Summary: NFSv4 user mapping not working
           Product: Base System
           Version: 14.2-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: jmmv@FreeBSD.org

I've set up a Kerberos domain (the KDC is on a pfSense box) and an NFSv4 server
which is on a Synology NAS.

I'm mounting the remote share on my FreeBSD 14.2-STABLE client with an entry in
fstab like this:

nas:/volume1/homes /shared nfs rw,nfsv4,gssname=host,sec=krb5p,pnfs 0 0

I have gssd and nfsuserd running, but when I list the contents of the
directory, I get:

$ ls -l /shared
total 0
drwxr-xr-x  1 nobody nogroup 0 Sep 27 21:11 admin
drwxr-xr-x  1 nobody nogroup 0 Nov  5 19:58 jmmv
drwxr-xr-x  1 nobody nogroup 0 Oct  8 16:59 manager

The "jmmv" directory should show up as owned by "jmmv", but it shows up as
"nobody".

When I start nfsuserd with -verbose set, I get:

nfsuserd: domain=meroh.net usermax=200 usertimeout=60

The domain meroh.net is the correct domain for the machine, and the Kerberos
domain name is MEROH.NET.

I've added logging statements to nfsuserd and can see that the GETUSER requests
from the kernel carry jmmv@MEROH.NET in them, which seems good, but still
things don't work.

In playing with the code, I modified the nfsuserd code with this:

------
--- a/usr.sbin/nfsuserd/nfsuserd.c
+++ b/usr.sbin/nfsuserd/nfsuserd.c
@@ -377,8 +377,15 @@ main(int argc, char *argv[])
        setgrent();
        while (i < nid.nid_usermax && (grp = getgrent())) {
                nid.nid_gid = grp->gr_gid;
-               nid.nid_name = grp->gr_name;
-               nid.nid_namelen = strlen(grp->gr_name);
+               char buf[1024];
+               snprintf(buf, sizeof(buf), "%s@%s", grp->gr_name, dnsname);
+               char *ptr = strchr(buf, '@');
+               while (*ptr != '\0') {
+                       *ptr = toupper(*ptr);
+                       ptr++;
+               }
+               nid.nid_name = buf;
+               nid.nid_namelen = strlen(nid.nid_name);
                nid.nid_ngroup = 0;
                nid.nid_grps = NULL;
                nid.nid_flag = NFSID_ADDGID;
@@ -416,8 +423,15 @@ main(int argc, char *argv[])
                        continue;
                check_dups[i - start_uidpos] = pwd->pw_uid;
                nid.nid_uid = pwd->pw_uid;
-               nid.nid_name = pwd->pw_name;
-               nid.nid_namelen = strlen(pwd->pw_name);
+               char buf[1024];
+               snprintf(buf, sizeof(buf), "%s@%s", pwd->pw_name, dnsname);
+               char *ptr = strchr(buf, '@');
+               while (*ptr != '\0') {
+                       *ptr = toupper(*ptr);
+                       ptr++;
+               }
+               nid.nid_name = buf;
+               nid.nid_namelen = strlen(nid.nid_name);
                if (manage_gids != 0) {
                        /* Get the group list for this user. */
                        ngroup = NGROUPS;
------

And got the usernames to work properly _after_ mount. This is insufficient when
the cache expires though because the above is only for the daemon
initialization, but seems to show that there is some inconsistency between what
nfsuserd thinks the domain should be expressed and what the kernel expects.

Note that, in the above, the toupper is important as well.

I do not know yet if this is a failure of my configuration or a bug in nfsuserd
/ the kernel.

Could you assist / confirm?

-- 
You are receiving this mail because:
You are the assignee for the bug.