[PATCH] nfsuserd: Preserve requested names in name-to-ID cache entries
Emanuel HelmsEmanuel Helms <[email protected]> Fri, 10 Jul 2026 20:32:51 +0200
| Newsgroups | gmane.os.freebsd.devel.file-systems |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. --------------XvFxnZFp0P5n3xL15Glmq6XG Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello Rick, I found an NFSv4 name-to-ID caching issue in nfsuserd on FreeBSD 15.1 and would appreciate your review of the attached patch. The setup in which I reproduced the issue consists of: - a FreeBSD 15.1 NFSv4 client; - Winbind as the passwd/group NSS backend; - an Active Directory domain provided by Samba on Rocky Linux 9; - RFC2307 uidNumber and gidNumber attributes in AD; - a Synology DSM 7.4 NFS server; and - a Kerberos-protected NFSv4.1 mount using sec=krb5i. An equivalent fstab entry is: nfs.example.org:/volume2/share /mnt/share nfs rw,nfsv4,minorversion=1,sec=krb5i 0 0 The corresponding manual mount command is: mount -t nfs -o nfsv4,minorversion=1,sec=krb5i \ nfs.example.org:/volume2/share /mnt/share The DSM server returns owner and owner_group attributes in a domain-qualified form, for example: EXAMPLE\[email protected] EXAMPLE\Domain [email protected] The configured NFSv4 domain is example.org. FreeBSD correctly removes the matching @example.org suffix before making the nfsuserd upcall. The resulting lookup names are therefore "EXAMPLE\alice" and "EXAMPLE\Domain Users". Winbind successfully resolves these names to the RFC2307 IDs. However, with "winbind use default domain = yes", getpwnam("EXAMPLE\alice") returns a passwd structure whose pw_name is the canonical short name "alice". The same canonicalization occurs for group lookups. RPCNFSUSERD_GETUSER currently inserts the successful mapping into the kernel cache using pwd->pw_name. The cache entry is therefore created for "alice", while nfsv4_strtouid() retries its lookup for the originally requested name "EXAMPLE\alice". That cache lookup misses and the owner is ultimately mapped to the default UID. RPCNFSUSERD_GETGROUP has the same behavior with grp->gr_name. This produces the following symptoms: - getent passwd 'EXAMPLE\alice' returns the correct RFC2307 UID; - getent group 'EXAMPLE\Domain Users' returns the correct RFC2307 GID; - Kerberos authentication and access to the export work; - nfsuserd -verbose logs that it found and added the correct numeric ID, but logs the canonical short name; and - stat(2) and ls(1) report 65534/65533 and nobody:nogroup for the NFS object. The attached patch changes only the two successful name-to-ID paths. The UID or GID still comes from the NSS result, but nid_name remains the exact name that caused the upcall. This lets the retry in nfsv4_strtouid() or nfsv4_strtogid() find the newly inserted entry. The ID-to-name paths, failed lookup behavior, timeout handling, group-list handling, Kerberos processing, and domain validation are unchanged. In the usual case where the requested and canonical NSS names are identical, the resulting cache key is also identical to the current one. After applying the patch and rebuilding nfsuserd, newly fetched attributes map to the expected RFC2307 UID and GID on the first lookup and on subsequent cached lookups. Short Winbind login names continue to work. I also verified that the source builds with the FreeBSD 15.1 build flags and warnings enabled. There is a possible broader benefit beyond Winbind: any NSS backend that successfully resolves an alias but returns a different canonical pw_name or gr_name can trigger the same mismatch. Caching the result under the name that was actually requested appears to match the semantics of NFSID_ADDUSERNAME and NFSID_ADDGROUPNAME. Please let me know if you would prefer the change in a different form or want additional diagnostics or testing. Best regards, Emanuel Helms --------------XvFxnZFp0P5n3xL15Glmq6XG Content-Type: text/plain; charset=UTF-8; name="0001-nfsuserd-preserve-requested-name-cache-keys.patch" Content-Disposition: attachment; filename="0001-nfsuserd-preserve-requested-name-cache-keys.patch" Content-Transfer-Encoding: base64 RnJvbSAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBFbWFudWVsIEhlbG1zIDxlbWFudWVsQG5ydi5jYz4K RGF0ZTogRnJpLCAxMCBKdWwgMjAyNiAxOTo0NTowMCArMDIwMApTdWJqZWN0OiBbUEFUQ0hd IG5mc3VzZXJkOiBQcmVzZXJ2ZSByZXF1ZXN0ZWQgbmFtZXMgaW4gbmFtZS10by1JRCBjYWNo ZSBlbnRyaWVzCgpBbiBOU1MgYmFja2VuZCBjYW4gcmVzb2x2ZSBhIHJlcXVlc3RlZCB1c2Vy IG9yIGdyb3VwIGFsaWFzIHdoaWxlIHJldHVybmluZyBhCmRpZmZlcmVudCBjYW5vbmljYWwg cHdfbmFtZSBvciBncl9uYW1lLiAgV2luYmluZCBkb2VzIHRoaXMgZm9yIGRvbWFpbi1xdWFs aWZpZWQKbmFtZXMgd2hlbiAid2luYmluZCB1c2UgZGVmYXVsdCBkb21haW4iIGlzIGVuYWJs ZWQuCgpUaGUgTkZTIGtlcm5lbCByZXRyaWVzIHRoZSBsb29rdXAgdXNpbmcgdGhlIG5hbWUg c2VudCBpbiB0aGUgdXBjYWxsLiAgQ2FjaGluZwp0aGUgcmVzdWx0IHVuZGVyIHRoZSBjYW5v bmljYWwgTlNTIG5hbWUgdGhlcmVmb3JlIGxlYXZlcyB0aGUgcmVxdWVzdGVkIG5hbWUKdW5t YXBwZWQsIGNhdXNpbmcgaXQgdG8gZmFsbCBiYWNrIHRvIG5vYm9keSBvciBub2dyb3VwLgoK Rm9yIHN1Y2Nlc3NmdWwgbmFtZS10by1JRCBsb29rdXBzLCByZXRhaW4gdGhlIGV4YWN0IHJl cXVlc3RlZCBuYW1lIGFzIHRoZQpjYWNoZSBrZXkuICBDb250aW51ZSB0byBvYnRhaW4gdGhl IG51bWVyaWMgVUlEIG9yIEdJRCBmcm9tIE5TUy4gIFRoZSByZXZlcnNlCklELXRvLW5hbWUg cGF0aHMgYW5kIGZhaWxlZCBsb29rdXAgYmVoYXZpb3IgcmVtYWluIHVuY2hhbmdlZC4KLS0t CiB1c3Iuc2Jpbi9uZnN1c2VyZC9uZnN1c2VyZC5jIHwgNiArKysrLS0KIDEgZmlsZSBjaGFu Z2VkLCA0IGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvdXNy LnNiaW4vbmZzdXNlcmQvbmZzdXNlcmQuYyBiL3Vzci5zYmluL25mc3VzZXJkL25mc3VzZXJk LmMKaW5kZXggOTMyNmRkOWE2ZDRmLi40N2M0YmE0OWIwZTEgMTAwNjQ0Ci0tLSBhL3Vzci5z YmluL25mc3VzZXJkL25mc3VzZXJkLmMKKysrIGIvdXNyLnNiaW4vbmZzdXNlcmQvbmZzdXNl cmQuYwpAQCAtNzA0LDcgKzcwNCw4IEBAIG5mc3VzZXJkc3J2KHN0cnVjdCBzdmNfcmVxICpy cXN0cCwgU1ZDWFBSVCAqdHJhbnNwKQogCQlpZiAocHdkICE9IE5VTEwpIHsKIAkJCW5pZC5u aWRfdXNlcnRpbWVvdXQgPSBkZWZ1c2VydGltZW91dDsKIAkJCW5pZC5uaWRfdWlkID0gcHdk LT5wd191aWQ7Ci0JCQluaWQubmlkX25hbWUgPSBwd2QtPnB3X25hbWU7CisJCQkvKiBOU1Mg bWF5IGNhbm9uaWNhbGl6ZSB0aGUgbmFtZSB1c2VkIGZvciB0aGUgbG9va3VwLiAqLworCQkJ bmlkLm5pZF9uYW1lID0gaW5mby5uYW1lOwogCQl9IGVsc2UgewogCQkJbmlkLm5pZF91c2Vy dGltZW91dCA9IDU7CiAJCQluaWQubmlkX3VpZCA9IGRlZmF1bHR1aWQ7CkBAIC03MzcsNyAr NzM4LDggQEAgbmZzdXNlcmRzcnYoc3RydWN0IHN2Y19yZXEgKnJxc3RwLCBTVkNYUFJUICp0 cmFuc3ApCiAJCWlmIChncnAgIT0gTlVMTCkgewogCQkJbmlkLm5pZF91c2VydGltZW91dCA9 IGRlZnVzZXJ0aW1lb3V0OwogCQkJbmlkLm5pZF9naWQgPSBncnAtPmdyX2dpZDsKLQkJCW5p ZC5uaWRfbmFtZSA9IGdycC0+Z3JfbmFtZTsKKwkJCS8qIE5TUyBtYXkgY2Fub25pY2FsaXpl IHRoZSBuYW1lIHVzZWQgZm9yIHRoZSBsb29rdXAuICovCisJCQluaWQubmlkX25hbWUgPSBp bmZvLm5hbWU7CiAJCX0gZWxzZSB7CiAJCQluaWQubmlkX3VzZXJ0aW1lb3V0ID0gNTsKIAkJ CW5pZC5uaWRfZ2lkID0gZGVmYXVsdGdpZDsKLS0gCjIuNTMuMAo= --------------XvFxnZFp0P5n3xL15Glmq6XG--