Modify the NFSv4 client so that it can handle owner
and owner_group strings that consist entirely of digits, interpreting them as the uid/gid number. This change was needed since new (>= 3.3) Linux servers reply with these strings by default. This change is mandated by the rfc3530bis draft. Reported on freebsd-stable@ under the Subject heading "Problem with Linux >= 3.3 as NFSv4 server" by Norbert Aschendorff on Aug. 20, 2012. Tested by: norbert.aschendorff at yahoo.de Reviewed by: jhb MFC after: 2 weeks
This commit is contained in:
parent
cc77b2d8e2
commit
c52005a31d
@ -559,6 +559,7 @@ struct nfsrv_descript {
|
||||
#define ND_EXGSSINTEGRITY 0x00200000
|
||||
#define ND_EXGSSPRIVACY 0x00400000
|
||||
#define ND_INCRSEQID 0x00800000
|
||||
#define ND_NFSCL 0x01000000
|
||||
|
||||
/*
|
||||
* ND_GSS should be the "or" of all GSS type authentications.
|
||||
|
@ -101,12 +101,12 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
|
||||
if (gotid == 0) {
|
||||
if (flag & NFSV4ACE_IDENTIFIERGROUP) {
|
||||
acep->ae_tag = ACL_GROUP;
|
||||
aceerr = nfsv4_strtogid(name, len, &gid, p);
|
||||
aceerr = nfsv4_strtogid(nd, name, len, &gid, p);
|
||||
if (aceerr == 0)
|
||||
acep->ae_id = (uid_t)gid;
|
||||
} else {
|
||||
acep->ae_tag = ACL_USER;
|
||||
aceerr = nfsv4_strtouid(name, len, &uid, p);
|
||||
aceerr = nfsv4_strtouid(nd, name, len, &uid, p);
|
||||
if (aceerr == 0)
|
||||
acep->ae_id = uid;
|
||||
}
|
||||
|
@ -1401,12 +1401,12 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
}
|
||||
if (compare) {
|
||||
if (!(*retcmpp)) {
|
||||
if (nfsv4_strtouid(cp, j, &uid, p) ||
|
||||
if (nfsv4_strtouid(nd, cp, j, &uid, p) ||
|
||||
nap->na_uid != uid)
|
||||
*retcmpp = NFSERR_NOTSAME;
|
||||
}
|
||||
} else if (nap != NULL) {
|
||||
if (nfsv4_strtouid(cp, j, &uid, p))
|
||||
if (nfsv4_strtouid(nd, cp, j, &uid, p))
|
||||
nap->na_uid = nfsrv_defaultuid;
|
||||
else
|
||||
nap->na_uid = uid;
|
||||
@ -1434,12 +1434,12 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
}
|
||||
if (compare) {
|
||||
if (!(*retcmpp)) {
|
||||
if (nfsv4_strtogid(cp, j, &gid, p) ||
|
||||
if (nfsv4_strtogid(nd, cp, j, &gid, p) ||
|
||||
nap->na_gid != gid)
|
||||
*retcmpp = NFSERR_NOTSAME;
|
||||
}
|
||||
} else if (nap != NULL) {
|
||||
if (nfsv4_strtogid(cp, j, &gid, p))
|
||||
if (nfsv4_strtogid(nd, cp, j, &gid, p))
|
||||
nap->na_gid = nfsrv_defaultgid;
|
||||
else
|
||||
nap->na_gid = gid;
|
||||
@ -2594,27 +2594,41 @@ nfsv4_uidtostr(uid_t uid, u_char **cpp, int *retlenp, NFSPROC_T *p)
|
||||
* Convert a string to a uid.
|
||||
* If no conversion is possible return NFSERR_BADOWNER, otherwise
|
||||
* return 0.
|
||||
* If this is called from a client side mount using AUTH_SYS and the
|
||||
* string is made up entirely of digits, just convert the string to
|
||||
* a number.
|
||||
*/
|
||||
APPLESTATIC int
|
||||
nfsv4_strtouid(u_char *str, int len, uid_t *uidp, NFSPROC_T *p)
|
||||
nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp,
|
||||
NFSPROC_T *p)
|
||||
{
|
||||
int i;
|
||||
u_char *cp;
|
||||
char *cp, *endstr, *str0;
|
||||
struct nfsusrgrp *usrp;
|
||||
int cnt, ret;
|
||||
int error = 0;
|
||||
uid_t tuid;
|
||||
|
||||
if (len == 0) {
|
||||
error = NFSERR_BADOWNER;
|
||||
goto out;
|
||||
}
|
||||
/* If a string of digits and an AUTH_SYS mount, just convert it. */
|
||||
str0 = str;
|
||||
tuid = (uid_t)strtoul(str0, &endstr, 10);
|
||||
if ((endstr - str0) == len &&
|
||||
(nd->nd_flag & (ND_KERBV | ND_NFSCL)) == ND_NFSCL) {
|
||||
*uidp = tuid;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Look for an '@'.
|
||||
*/
|
||||
cp = str;
|
||||
for (i = 0; i < len; i++)
|
||||
if (*cp++ == '@')
|
||||
break;
|
||||
cp = strchr(str0, '@');
|
||||
if (cp != NULL)
|
||||
i = (int)(cp++ - str0);
|
||||
else
|
||||
i = len;
|
||||
|
||||
cnt = 0;
|
||||
tryagain:
|
||||
@ -2783,27 +2797,43 @@ nfsv4_gidtostr(gid_t gid, u_char **cpp, int *retlenp, NFSPROC_T *p)
|
||||
|
||||
/*
|
||||
* Convert a string to a gid.
|
||||
* If no conversion is possible return NFSERR_BADOWNER, otherwise
|
||||
* return 0.
|
||||
* If this is called from a client side mount using AUTH_SYS and the
|
||||
* string is made up entirely of digits, just convert the string to
|
||||
* a number.
|
||||
*/
|
||||
APPLESTATIC int
|
||||
nfsv4_strtogid(u_char *str, int len, gid_t *gidp, NFSPROC_T *p)
|
||||
nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp,
|
||||
NFSPROC_T *p)
|
||||
{
|
||||
int i;
|
||||
u_char *cp;
|
||||
char *cp, *endstr, *str0;
|
||||
struct nfsusrgrp *usrp;
|
||||
int cnt, ret;
|
||||
int error = 0;
|
||||
gid_t tgid;
|
||||
|
||||
if (len == 0) {
|
||||
error = NFSERR_BADOWNER;
|
||||
goto out;
|
||||
}
|
||||
/* If a string of digits and an AUTH_SYS mount, just convert it. */
|
||||
str0 = str;
|
||||
tgid = (gid_t)strtoul(str0, &endstr, 10);
|
||||
if ((endstr - str0) == len &&
|
||||
(nd->nd_flag & (ND_KERBV | ND_NFSCL)) == ND_NFSCL) {
|
||||
*gidp = tgid;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Look for an '@'.
|
||||
*/
|
||||
cp = str;
|
||||
for (i = 0; i < len; i++)
|
||||
if (*cp++ == '@')
|
||||
break;
|
||||
cp = strchr(str0, '@');
|
||||
if (cp != NULL)
|
||||
i = (int)(cp++ - str0);
|
||||
else
|
||||
i = len;
|
||||
|
||||
cnt = 0;
|
||||
tryagain:
|
||||
|
@ -295,9 +295,11 @@ 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 *);
|
||||
int nfsv4_strtouid(u_char *, int, uid_t *, 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 nfsv4_strtogid(u_char *, int, gid_t *, NFSPROC_T *);
|
||||
int nfsv4_strtogid(struct nfsrv_descript *, u_char *, int, gid_t *,
|
||||
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 *,
|
||||
|
@ -126,11 +126,11 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
|
||||
* First, fill in some of the fields of nd.
|
||||
*/
|
||||
if (NFSHASNFSV4(nmp))
|
||||
nd->nd_flag = ND_NFSV4;
|
||||
nd->nd_flag = ND_NFSV4 | ND_NFSCL;
|
||||
else if (NFSHASNFSV3(nmp))
|
||||
nd->nd_flag = ND_NFSV3;
|
||||
nd->nd_flag = ND_NFSV3 | ND_NFSCL;
|
||||
else
|
||||
nd->nd_flag = ND_NFSV2;
|
||||
nd->nd_flag = ND_NFSV2 | ND_NFSCL;
|
||||
nd->nd_procnum = procnum;
|
||||
nd->nd_repstat = 0;
|
||||
|
||||
|
@ -2437,7 +2437,8 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
goto nfsmout;
|
||||
}
|
||||
if (!nd->nd_repstat) {
|
||||
nd->nd_repstat = nfsv4_strtouid(cp,j,&uid,p);
|
||||
nd->nd_repstat = nfsv4_strtouid(nd, cp, j, &uid,
|
||||
p);
|
||||
if (!nd->nd_repstat)
|
||||
nvap->na_uid = uid;
|
||||
}
|
||||
@ -2463,7 +2464,8 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
goto nfsmout;
|
||||
}
|
||||
if (!nd->nd_repstat) {
|
||||
nd->nd_repstat = nfsv4_strtogid(cp,j,&gid,p);
|
||||
nd->nd_repstat = nfsv4_strtogid(nd, cp, j, &gid,
|
||||
p);
|
||||
if (!nd->nd_repstat)
|
||||
nvap->na_gid = gid;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user