Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Oct 2012 12:43:45 +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-9@freebsd.org
Subject:   svn commit: r241194 - in stable/9/sys/fs: nfs nfsclient nfsserver
Message-ID:  <201210041243.q94ChjmO055465@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Thu Oct  4 12:43:45 2012
New Revision: 241194
URL: http://svn.freebsd.org/changeset/base/241194

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/9/sys/fs/nfs/nfs.h
  stable/9/sys/fs/nfs/nfs_commonacl.c
  stable/9/sys/fs/nfs/nfs_commonsubs.c
  stable/9/sys/fs/nfs/nfs_var.h
  stable/9/sys/fs/nfsclient/nfs_clcomsubs.c
  stable/9/sys/fs/nfsserver/nfs_nfsdport.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)
  stable/9/sys/dev/   (props changed)
  stable/9/sys/dev/e1000/   (props changed)
  stable/9/sys/dev/isp/   (props changed)
  stable/9/sys/dev/ixgbe/   (props changed)
  stable/9/sys/dev/puc/   (props changed)
  stable/9/sys/fs/   (props changed)
  stable/9/sys/fs/ntfs/   (props changed)
  stable/9/sys/modules/   (props changed)

Modified: stable/9/sys/fs/nfs/nfs.h
==============================================================================
--- stable/9/sys/fs/nfs/nfs.h	Thu Oct  4 09:53:59 2012	(r241193)
+++ stable/9/sys/fs/nfs/nfs.h	Thu Oct  4 12:43:45 2012	(r241194)
@@ -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/9/sys/fs/nfs/nfs_commonacl.c
==============================================================================
--- stable/9/sys/fs/nfs/nfs_commonacl.c	Thu Oct  4 09:53:59 2012	(r241193)
+++ stable/9/sys/fs/nfs/nfs_commonacl.c	Thu Oct  4 12:43:45 2012	(r241194)
@@ -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/9/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- stable/9/sys/fs/nfs/nfs_commonsubs.c	Thu Oct  4 09:53:59 2012	(r241193)
+++ stable/9/sys/fs/nfs/nfs_commonsubs.c	Thu Oct  4 12:43:45 2012	(r241194)
@@ -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/9/sys/fs/nfs/nfs_var.h
==============================================================================
--- stable/9/sys/fs/nfs/nfs_var.h	Thu Oct  4 09:53:59 2012	(r241193)
+++ stable/9/sys/fs/nfs/nfs_var.h	Thu Oct  4 12:43:45 2012	(r241194)
@@ -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/9/sys/fs/nfsclient/nfs_clcomsubs.c
==============================================================================
--- stable/9/sys/fs/nfsclient/nfs_clcomsubs.c	Thu Oct  4 09:53:59 2012	(r241193)
+++ stable/9/sys/fs/nfsclient/nfs_clcomsubs.c	Thu Oct  4 12:43:45 2012	(r241194)
@@ -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/9/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- stable/9/sys/fs/nfsserver/nfs_nfsdport.c	Thu Oct  4 09:53:59 2012	(r241193)
+++ stable/9/sys/fs/nfsserver/nfs_nfsdport.c	Thu Oct  4 12:43:45 2012	(r241194)
@@ -2438,7 +2438,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;
 			}
@@ -2464,7 +2465,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?201210041243.q94ChjmO055465>