Date: Sat, 6 Oct 2012 22:14:19 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r241306 - in stable/8/sys/fs: nfs nfsclient nfsserver Message-ID: <201210062214.q96MEJ8b051951@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sat Oct 6 22:14:19 2012 New Revision: 241306 URL: http://svn.freebsd.org/changeset/base/241306 Log: MFC: r240720 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. Modified: stable/8/sys/fs/nfs/nfs.h stable/8/sys/fs/nfs/nfs_commonacl.c stable/8/sys/fs/nfs/nfs_commonsubs.c stable/8/sys/fs/nfs/nfs_var.h stable/8/sys/fs/nfsclient/nfs_clcomsubs.c stable/8/sys/fs/nfsserver/nfs_nfsdport.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/fs/ (props changed) Modified: stable/8/sys/fs/nfs/nfs.h ============================================================================== --- stable/8/sys/fs/nfs/nfs.h Sat Oct 6 21:42:07 2012 (r241305) +++ stable/8/sys/fs/nfs/nfs.h Sat Oct 6 22:14:19 2012 (r241306) @@ -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. Modified: stable/8/sys/fs/nfs/nfs_commonacl.c ============================================================================== --- stable/8/sys/fs/nfs/nfs_commonacl.c Sat Oct 6 21:42:07 2012 (r241305) +++ stable/8/sys/fs/nfs/nfs_commonacl.c Sat Oct 6 22:14:19 2012 (r241306) @@ -101,12 +101,12 @@ nfsrv_dissectace(struct nfsrv_descript * 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; } Modified: stable/8/sys/fs/nfs/nfs_commonsubs.c ============================================================================== --- stable/8/sys/fs/nfs/nfs_commonsubs.c Sat Oct 6 21:42:07 2012 (r241305) +++ stable/8/sys/fs/nfs/nfs_commonsubs.c Sat Oct 6 22:14:19 2012 (r241306) @@ -1401,12 +1401,12 @@ nfsv4_loadattr(struct nfsrv_descript *nd } 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 } 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 @@ tryagain: * 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 @@ tryagain: /* * 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: Modified: stable/8/sys/fs/nfs/nfs_var.h ============================================================================== --- stable/8/sys/fs/nfs/nfs_var.h Sat Oct 6 21:42:07 2012 (r241305) +++ stable/8/sys/fs/nfs/nfs_var.h Sat Oct 6 22:14:19 2012 (r241306) @@ -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 *, Modified: stable/8/sys/fs/nfsclient/nfs_clcomsubs.c ============================================================================== --- stable/8/sys/fs/nfsclient/nfs_clcomsubs.c Sat Oct 6 21:42:07 2012 (r241305) +++ stable/8/sys/fs/nfsclient/nfs_clcomsubs.c Sat Oct 6 22:14:19 2012 (r241306) @@ -126,11 +126,11 @@ nfscl_reqstart(struct nfsrv_descript *nd * 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; Modified: stable/8/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- stable/8/sys/fs/nfsserver/nfs_nfsdport.c Sat Oct 6 21:42:07 2012 (r241305) +++ stable/8/sys/fs/nfsserver/nfs_nfsdport.c Sat Oct 6 22:14:19 2012 (r241306) @@ -2433,7 +2433,8 @@ nfsv4_sattr(struct nfsrv_descript *nd, s 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; } @@ -2459,7 +2460,8 @@ nfsv4_sattr(struct nfsrv_descript *nd, s 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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210062214.q96MEJ8b051951>