From owner-svn-src-head@FreeBSD.ORG Thu Sep 20 02:49:26 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 3FABE1065670; Thu, 20 Sep 2012 02:49:26 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2977E8FC0C; Thu, 20 Sep 2012 02:49:26 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8K2nPNX025209; Thu, 20 Sep 2012 02:49:25 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8K2nPoM025202; Thu, 20 Sep 2012 02:49:25 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201209200249.q8K2nPoM025202@svn.freebsd.org> From: Rick Macklem Date: Thu, 20 Sep 2012 02:49:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240720 - in head/sys/fs: nfs nfsclient nfsserver X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Sep 2012 02:49:26 -0000 Author: rmacklem Date: Thu Sep 20 02:49:25 2012 New Revision: 240720 URL: http://svn.freebsd.org/changeset/base/240720 Log: 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 Modified: head/sys/fs/nfs/nfs.h head/sys/fs/nfs/nfs_commonacl.c head/sys/fs/nfs/nfs_commonsubs.c head/sys/fs/nfs/nfs_var.h head/sys/fs/nfsclient/nfs_clcomsubs.c head/sys/fs/nfsserver/nfs_nfsdport.c Modified: head/sys/fs/nfs/nfs.h ============================================================================== --- head/sys/fs/nfs/nfs.h Thu Sep 20 02:25:18 2012 (r240719) +++ head/sys/fs/nfs/nfs.h Thu Sep 20 02:49:25 2012 (r240720) @@ -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: head/sys/fs/nfs/nfs_commonacl.c ============================================================================== --- head/sys/fs/nfs/nfs_commonacl.c Thu Sep 20 02:25:18 2012 (r240719) +++ head/sys/fs/nfs/nfs_commonacl.c Thu Sep 20 02:49:25 2012 (r240720) @@ -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: head/sys/fs/nfs/nfs_commonsubs.c ============================================================================== --- head/sys/fs/nfs/nfs_commonsubs.c Thu Sep 20 02:25:18 2012 (r240719) +++ head/sys/fs/nfs/nfs_commonsubs.c Thu Sep 20 02:49:25 2012 (r240720) @@ -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: head/sys/fs/nfs/nfs_var.h ============================================================================== --- head/sys/fs/nfs/nfs_var.h Thu Sep 20 02:25:18 2012 (r240719) +++ head/sys/fs/nfs/nfs_var.h Thu Sep 20 02:49:25 2012 (r240720) @@ -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: head/sys/fs/nfsclient/nfs_clcomsubs.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clcomsubs.c Thu Sep 20 02:25:18 2012 (r240719) +++ head/sys/fs/nfsclient/nfs_clcomsubs.c Thu Sep 20 02:49:25 2012 (r240720) @@ -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: head/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- head/sys/fs/nfsserver/nfs_nfsdport.c Thu Sep 20 02:25:18 2012 (r240719) +++ head/sys/fs/nfsserver/nfs_nfsdport.c Thu Sep 20 02:49:25 2012 (r240720) @@ -2437,7 +2437,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; } @@ -2463,7 +2464,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; }