--- sys/fs/nfsclient/nfs_clrpcops.c.sav 2012-12-26 17:29:46.000000000 -0500 +++ sys/fs/nfsclient/nfs_clrpcops.c 2012-12-26 17:30:10.000000000 -0500 @@ -487,7 +487,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vno if (ret) ndp->nfsdl_flags |= NFSCLDL_RECALL; error = nfsrv_dissectace(nd, &ndp->nfsdl_ace, &ret, - &acesize, p); + &acesize, 0, p); if (error) goto nfsmout; } else if (deleg != NFSV4OPEN_DELEGATENONE) { @@ -2068,7 +2068,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, if (ret) dp->nfsdl_flags |= NFSCLDL_RECALL; error = nfsrv_dissectace(nd, &dp->nfsdl_ace, &ret, - &acesize, p); + &acesize, 0, p); if (error) goto nfsmout; } else if (deleg != NFSV4OPEN_DELEGATENONE) { --- sys/fs/nfs/nfs_commonsubs.c.sav 2012-12-26 16:37:39.000000000 -0500 +++ sys/fs/nfs/nfs_commonsubs.c 2012-12-27 14:40:38.000000000 -0500 @@ -680,7 +680,7 @@ nfsmout: */ APPLESTATIC int nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp, - int *aclsizep, __unused NFSPROC_T *p) + int *aclsizep, int setattr, __unused NFSPROC_T *p) { u_int32_t *tl; int i, aclsize; @@ -703,7 +703,7 @@ nfsrv_dissectacl(struct nfsrv_descript * for (i = 0; i < acecnt; i++) { if (aclp && !aceerr) error = nfsrv_dissectace(nd, &aclp->acl_entry[i], - &aceerr, &acesize, p); + &aceerr, &acesize, setattr, p); else error = nfsrv_skipace(nd, &acesize); if (error) @@ -1053,7 +1053,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd naclp = acl_alloc(M_WAITOK); error = nfsrv_dissectacl(nd, naclp, &aceerr, - &cnt, p); + &cnt, 0, p); if (error) { acl_free(naclp); goto nfsmout; @@ -1064,17 +1064,17 @@ nfsv4_loadattr(struct nfsrv_descript *nd acl_free(naclp); } else { error = nfsrv_dissectacl(nd, NULL, &aceerr, - &cnt, p); + &cnt, 0, p); *retcmpp = NFSERR_ATTRNOTSUPP; } } } else { if (vp != NULL && aclp != NULL) error = nfsrv_dissectacl(nd, aclp, &aceerr, - &cnt, p); + &cnt, 0, p); else error = nfsrv_dissectacl(nd, NULL, &aceerr, - &cnt, p); + &cnt, 0, p); if (error) goto nfsmout; } @@ -1420,12 +1420,12 @@ nfsv4_loadattr(struct nfsrv_descript *nd } if (compare) { if (!(*retcmpp)) { - if (nfsv4_strtouid(nd, cp, j, &uid, p) || + if (nfsv4_strtouid(nd, cp, j, &uid, 0, p) || nap->na_uid != uid) *retcmpp = NFSERR_NOTSAME; } } else if (nap != NULL) { - if (nfsv4_strtouid(nd, cp, j, &uid, p)) + if (nfsv4_strtouid(nd, cp, j, &uid, 0, p)) nap->na_uid = nfsrv_defaultuid; else nap->na_uid = uid; @@ -1453,12 +1453,12 @@ nfsv4_loadattr(struct nfsrv_descript *nd } if (compare) { if (!(*retcmpp)) { - if (nfsv4_strtogid(nd, cp, j, &gid, p) || + if (nfsv4_strtogid(nd, cp, j, &gid, 0, p) || nap->na_gid != gid) *retcmpp = NFSERR_NOTSAME; } } else if (nap != NULL) { - if (nfsv4_strtogid(nd, cp, j, &gid, p)) + if (nfsv4_strtogid(nd, cp, j, &gid, 0, p)) nap->na_gid = nfsrv_defaultgid; else nap->na_gid = gid; @@ -1987,7 +1987,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram, int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno) { - int bitpos, retnum = 0; + int bitpos, retnum = 0, setattr; u_int32_t *tl; int siz, prefixnum, error; u_char *cp, namestr[NFSV4_SMALLSTR]; @@ -2013,10 +2013,12 @@ nfsv4_fillattr(struct nfsrv_descript *nd if (p == NULL && cred == NULL) { NFSCLRNOTSETABLE_ATTRBIT(retbitp); aclp = saclp; + setattr = 1; } else { NFSCLRNOTFILLABLE_ATTRBIT(retbitp); naclp = acl_alloc(M_WAITOK); aclp = naclp; + setattr = 0; } nfsvno_getfs(&fsinf, isdgram); #ifndef APPLE @@ -2156,7 +2158,8 @@ nfsv4_fillattr(struct nfsrv_descript *nd * Recommended Attributes. (Only the supported ones.) */ case NFSATTRBIT_ACL: - retnum += nfsrv_buildacl(nd, aclp, vnode_vtype(vp), p); + retnum += nfsrv_buildacl(nd, aclp, vnode_vtype(vp), + setattr, p); break; case NFSATTRBIT_ACLSUPPORT: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); @@ -2290,14 +2293,14 @@ nfsv4_fillattr(struct nfsrv_descript *nd break; case NFSATTRBIT_OWNER: cp = namestr; - nfsv4_uidtostr(vap->va_uid, &cp, &siz, p); + nfsv4_uidtostr(vap->va_uid, &cp, &siz, setattr, p); retnum += nfsm_strtom(nd, cp, siz); if (cp != namestr) free(cp, M_NFSSTRING); break; case NFSATTRBIT_OWNERGROUP: cp = namestr; - nfsv4_gidtostr(vap->va_gid, &cp, &siz, p); + nfsv4_gidtostr(vap->va_gid, &cp, &siz, setattr, p); retnum += nfsm_strtom(nd, cp, siz); if (cp != namestr) free(cp, M_NFSSTRING); @@ -2504,7 +2507,7 @@ nfsrv_putattrbit(struct nfsrv_descript * * retlenp - pointer to length to be returned */ APPLESTATIC void -nfsv4_uidtostr(uid_t uid, u_char **cpp, int *retlenp, NFSPROC_T *p) +nfsv4_uidtostr(uid_t uid, u_char **cpp, int *retlenp, int setattr, NFSPROC_T *p) { int i; struct nfsusrgrp *usrp; @@ -2542,6 +2545,9 @@ tryagain: if (usrp->lug_uid == uid) { if (usrp->lug_expiry < NFSD_MONOSEC) break; + if ((usrp->lug_flag & NFSLUG_DEFAULT) != 0 && + setattr != 0) + break; /* * If the name doesn't already have an '@' * in it, append @domainname to it. @@ -2619,7 +2625,7 @@ tryagain: */ APPLESTATIC int nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp, - NFSPROC_T *p) + int setattr, NFSPROC_T *p) { int i; char *cp, *endstr, *str0; @@ -2680,6 +2686,9 @@ tryagain: !NFSBCMP(usrp->lug_name, str, len)) { if (usrp->lug_expiry < NFSD_MONOSEC) break; + if ((usrp->lug_flag & NFSLUG_DEFAULT) != 0 && + setattr != 0) + break; *uidp = usrp->lug_uid; TAILQ_REMOVE(&nfsuserlruhead, usrp, lug_lru); TAILQ_INSERT_TAIL(&nfsuserlruhead, usrp, lug_lru); @@ -2709,7 +2718,7 @@ out: * retlenp - pointer to length to be returned */ APPLESTATIC void -nfsv4_gidtostr(gid_t gid, u_char **cpp, int *retlenp, NFSPROC_T *p) +nfsv4_gidtostr(gid_t gid, u_char **cpp, int *retlenp, int setattr, NFSPROC_T *p) { int i; struct nfsusrgrp *usrp; @@ -2747,6 +2756,9 @@ tryagain: if (usrp->lug_gid == gid) { if (usrp->lug_expiry < NFSD_MONOSEC) break; + if ((usrp->lug_flag & NFSLUG_DEFAULT) != 0 && + setattr != 0) + break; /* * If the name doesn't already have an '@' * in it, append @domainname to it. @@ -2824,7 +2836,7 @@ tryagain: */ APPLESTATIC int nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp, - NFSPROC_T *p) + int setattr, NFSPROC_T *p) { int i; char *cp, *endstr, *str0; @@ -2883,6 +2895,9 @@ tryagain: !NFSBCMP(usrp->lug_name, str, len)) { if (usrp->lug_expiry < NFSD_MONOSEC) break; + if ((usrp->lug_flag & NFSLUG_DEFAULT) != 0 && + setattr != 0) + break; *gidp = usrp->lug_gid; TAILQ_REMOVE(&nfsuserlruhead, usrp, lug_lru); TAILQ_INSERT_TAIL(&nfsuserlruhead, usrp, lug_lru); @@ -3115,6 +3130,9 @@ nfssvc_idname(struct nfsd_idargs *nidp) goto out; } newusrp->lug_namelen = nidp->nid_namelen; + newusrp->lug_flag = 0; + if ((nidp->nid_flag & NFSID_DEFAULT) != 0) + newusrp->lug_flag |= NFSLUG_DEFAULT; NFSLOCKNAMEID(); /* --- sys/fs/nfs/nfsrvstate.h.sav 2012-12-26 16:48:49.000000000 -0500 +++ sys/fs/nfs/nfsrvstate.h 2012-12-26 16:49:59.000000000 -0500 @@ -226,12 +226,18 @@ struct nfsusrgrp { gid_t un_gid; } lug_un; int lug_namelen; /* Name length */ + u_char lug_flag; /* Flag bits */ u_char lug_name[1]; /* malloc'd correct length */ }; #define lug_uid lug_un.un_uid #define lug_gid lug_un.un_gid /* + * Flag bits for lug_flag. + */ +#define NFSLUG_DEFAULT 0x01 + +/* * These structures are used for the stable storage restart stuff. */ /* --- sys/fs/nfs/nfs.h.sav 2012-12-26 16:50:23.000000000 -0500 +++ sys/fs/nfs/nfs.h 2012-12-26 16:50:53.000000000 -0500 @@ -329,6 +329,7 @@ struct nfsreferral { #define NFSID_DELGID 0x0040 #define NFSID_ADDGROUPNAME 0x0080 #define NFSID_DELGROUPNAME 0x0100 +#define NFSID_DEFAULT 0x0200 /* * fs.nfs sysctl(3) identifiers --- sys/fs/nfs/nfs_commonacl.c.sav 2012-12-26 17:06:49.000000000 -0500 +++ sys/fs/nfs/nfs_commonacl.c 2012-12-27 14:03:01.000000000 -0500 @@ -42,7 +42,7 @@ static int nfsrv_acemasktoperm(u_int32_t */ APPLESTATIC int nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep, - int *aceerrp, int *acesizep, NFSPROC_T *p) + int *aceerrp, int *acesizep, int setattr, NFSPROC_T *p) { u_int32_t *tl; int len, gotid = 0, owner = 0, error = 0, aceerr = 0; @@ -101,12 +101,14 @@ nfsrv_dissectace(struct nfsrv_descript * if (gotid == 0) { if (flag & NFSV4ACE_IDENTIFIERGROUP) { acep->ae_tag = ACL_GROUP; - aceerr = nfsv4_strtogid(nd, name, len, &gid, p); + aceerr = nfsv4_strtogid(nd, name, len, &gid, setattr, + p); if (aceerr == 0) acep->ae_id = (uid_t)gid; } else { acep->ae_tag = ACL_USER; - aceerr = nfsv4_strtouid(nd, name, len, &uid, p); + aceerr = nfsv4_strtouid(nd, name, len, &uid, setattr, + p); if (aceerr == 0) acep->ae_id = uid; } @@ -388,7 +390,7 @@ nfsrv_buildace(struct nfsrv_descript *nd */ APPLESTATIC int nfsrv_buildacl(struct nfsrv_descript *nd, NFSACL_T *aclp, enum vtype type, - NFSPROC_T *p) + int setattr, NFSPROC_T *p) { int i, entrycnt = 0, retlen; u_int32_t *entrycntp; @@ -420,7 +422,7 @@ nfsrv_buildacl(struct nfsrv_descript *nd case ACL_USER: name = namestr; nfsv4_uidtostr(aclp->acl_entry[i].ae_id, &name, - &namelen, p); + &namelen, setattr, p); if (name != namestr) malloced = 1; break; @@ -428,7 +430,7 @@ nfsrv_buildacl(struct nfsrv_descript *nd isgroup = 1; name = namestr; nfsv4_gidtostr((gid_t)aclp->acl_entry[i].ae_id, &name, - &namelen, p); + &namelen, setattr, p); if (name != namestr) malloced = 1; break; --- sys/fs/nfs/nfs_var.h.sav 2012-12-26 17:26:28.000000000 -0500 +++ sys/fs/nfs/nfs_var.h 2012-12-27 14:00:38.000000000 -0500 @@ -242,7 +242,7 @@ void newnfs_trimtrailing(struct nfsrv_de void newnfs_copycred(struct nfscred *, struct ucred *); void newnfs_copyincred(struct ucred *, struct nfscred *); int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, int *, - int *, NFSPROC_T *); + int *, int, NFSPROC_T *); int nfsrv_getattrbits(struct nfsrv_descript *, nfsattrbit_t *, int *, int *); int nfsv4_loadattr(struct nfsrv_descript *, vnode_t, @@ -304,12 +304,12 @@ void nfsrv_fillattr(struct nfsrv_descrip void nfsrv_adj(mbuf_t, int, int); void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *); int nfsd_errmap(struct nfsrv_descript *); -void nfsv4_uidtostr(uid_t, u_char **, int *, NFSPROC_T *); +void nfsv4_uidtostr(uid_t, u_char **, int *, int, NFSPROC_T *); int nfsv4_strtouid(struct nfsrv_descript *, u_char *, int, uid_t *, - NFSPROC_T *); -void nfsv4_gidtostr(gid_t, u_char **, int *, NFSPROC_T *); + int, NFSPROC_T *); +void nfsv4_gidtostr(gid_t, u_char **, int *, int, NFSPROC_T *); int nfsv4_strtogid(struct nfsrv_descript *, u_char *, int, gid_t *, - NFSPROC_T *); + int, NFSPROC_T *); int nfsrv_checkuidgid(struct nfsrv_descript *, struct nfsvattr *); void nfsrv_fixattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, NFSACL_T *, NFSPROC_T *, nfsattrbit_t *, @@ -346,9 +346,9 @@ int nfs_supportsnfsv4acls(vnode_t); /* nfs_commonacl.c */ int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *, - int *, int *, NFSPROC_T *); + int *, int *, int, NFSPROC_T *); int nfsrv_buildacl(struct nfsrv_descript *, NFSACL_T *, enum vtype, - NFSPROC_T *); + int, NFSPROC_T *); int nfsrv_setacl(vnode_t, NFSACL_T *, struct ucred *, NFSPROC_T *); int nfsrv_compareacl(NFSACL_T *, NFSACL_T *); --- sys/fs/nfsserver/nfs_nfsdport.c.sav 2012-12-26 17:09:08.000000000 -0500 +++ sys/fs/nfsserver/nfs_nfsdport.c 2012-12-26 17:20:13.000000000 -0500 @@ -2385,7 +2385,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, s break; case NFSATTRBIT_ACL: error = nfsrv_dissectacl(nd, aclp, &aceerr, &aclsize, - p); + 1, p); if (error) goto nfsmout; if (aceerr && !nd->nd_repstat) @@ -2438,7 +2438,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, s } if (!nd->nd_repstat) { nd->nd_repstat = nfsv4_strtouid(nd, cp, j, &uid, - p); + 1, p); if (!nd->nd_repstat) nvap->na_uid = uid; } @@ -2465,7 +2465,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, s } if (!nd->nd_repstat) { nd->nd_repstat = nfsv4_strtogid(nd, cp, j, &gid, - p); + 1, p); if (!nd->nd_repstat) nvap->na_gid = gid; } --- usr.sbin/nfsuserd/nfsuserd.c.sav 2012-12-26 17:45:04.000000000 -0500 +++ usr.sbin/nfsuserd/nfsuserd.c 2012-12-27 14:13:24.933737000 -0500 @@ -468,6 +468,7 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP } pwd = getpwuid((uid_t)info.id); info.retval = 0; + nid.nid_flag = NFSID_ADDUID; if (pwd != NULL) { nid.nid_usertimeout = defusertimeout; nid.nid_uid = pwd->pw_uid; @@ -476,9 +477,9 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP nid.nid_usertimeout = 5; nid.nid_uid = (uid_t)info.id; nid.nid_name = defaultuser; + nid.nid_flag |= NFSID_DEFAULT; } nid.nid_namelen = strlen(nid.nid_name); - nid.nid_flag = NFSID_ADDUID; error = nfssvc(NFSSVC_IDNAME, &nid); if (error) { info.retval = error; @@ -499,6 +500,7 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP } grp = getgrgid((gid_t)info.id); info.retval = 0; + nid.nid_flag = NFSID_ADDGID; if (grp != NULL) { nid.nid_usertimeout = defusertimeout; nid.nid_gid = grp->gr_gid; @@ -507,9 +509,9 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP nid.nid_usertimeout = 5; nid.nid_gid = (gid_t)info.id; nid.nid_name = defaultgroup; + nid.nid_flag |= NFSID_DEFAULT; } nid.nid_namelen = strlen(nid.nid_name); - nid.nid_flag = NFSID_ADDGID; error = nfssvc(NFSSVC_IDNAME, &nid); if (error) { info.retval = error; @@ -531,6 +533,7 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP } pwd = getpwnam(info.name); info.retval = 0; + nid.nid_flag = NFSID_ADDUSERNAME; if (pwd != NULL) { nid.nid_usertimeout = defusertimeout; nid.nid_uid = pwd->pw_uid; @@ -539,9 +542,9 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP nid.nid_usertimeout = 5; nid.nid_uid = defaultuid; nid.nid_name = info.name; + nid.nid_flag |= NFSID_DEFAULT; } nid.nid_namelen = strlen(nid.nid_name); - nid.nid_flag = NFSID_ADDUSERNAME; error = nfssvc(NFSSVC_IDNAME, &nid); if (error) { info.retval = error; @@ -562,6 +565,7 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP } grp = getgrnam(info.name); info.retval = 0; + nid.nid_flag = NFSID_ADDGROUPNAME; if (grp != NULL) { nid.nid_usertimeout = defusertimeout; nid.nid_gid = grp->gr_gid; @@ -570,9 +574,9 @@ nfsuserdsrv(struct svc_req *rqstp, SVCXP nid.nid_usertimeout = 5; nid.nid_gid = defaultgid; nid.nid_name = info.name; + nid.nid_flag |= NFSID_DEFAULT; } nid.nid_namelen = strlen(nid.nid_name); - nid.nid_flag = NFSID_ADDGROUPNAME; error = nfssvc(NFSSVC_IDNAME, &nid); if (error) { info.retval = error;