svn commit: r294124 - stable/10/usr.sbin/mountd

Josh Paetzel jpaetzel at FreeBSD.org
Sat Jan 16 01:40:48 UTC 2016


Author: jpaetzel
Date: Sat Jan 16 01:40:46 2016
New Revision: 294124
URL: https://svnweb.freebsd.org/changeset/base/294124

Log:
  MFC 293305
  
  Allow /etc/exports to contain usernames/groups with spaces in them.
  
  If you are getting your users/groups from a directory service such
  as LDAP or AD it's possible for those usernames or groupnames to
  contain spaces.
  
  Submitted by:	Sean E. Fagan
  Reviewed by:	rmacklem
  Sponsored by:	iXsystems

Modified:
  stable/10/usr.sbin/mountd/exports.5
  stable/10/usr.sbin/mountd/mountd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/mountd/exports.5
==============================================================================
--- stable/10/usr.sbin/mountd/exports.5	Sat Jan 16 01:37:17 2016	(r294123)
+++ stable/10/usr.sbin/mountd/exports.5	Sat Jan 16 01:40:46 2016	(r294124)
@@ -131,6 +131,7 @@ The credential includes all the groups t
 on the local machine (see
 .Xr id 1 ) .
 The user may be specified by name or number.
+The user string may be quoted, or use backslash escaping.
 .Pp
 .Sm off
 .Fl maproot Li = Sy user:group1:group2:...
@@ -140,6 +141,7 @@ to be used for remote access by root.
 The elements of the list may be either names or numbers.
 Note that user: should be used to distinguish a credential containing
 no groups from a complete credential for that user.
+The group names may be quoted, or use backslash escaping.
 .Pp
 .Sm off
 .Fl mapall Li = Sy user

Modified: stable/10/usr.sbin/mountd/mountd.c
==============================================================================
--- stable/10/usr.sbin/mountd/mountd.c	Sat Jan 16 01:37:17 2016	(r294123)
+++ stable/10/usr.sbin/mountd/mountd.c	Sat Jan 16 01:40:46 2016	(r294124)
@@ -174,6 +174,7 @@ int	check_options(struct dirlist *);
 int	checkmask(struct sockaddr *sa);
 int	chk_host(struct dirlist *, struct sockaddr *, int *, int *, int *,
 				 int **);
+static char	*strsep_quote(char **stringp, const char *delim);
 static int	create_service(struct netconfig *nconf);
 static void	complete_service(struct netconfig *nconf, char *port_str);
 static void	clearout_service(void);
@@ -278,6 +279,73 @@ int debug = 0;
 #endif
 
 /*
+ * Similar to strsep(), but it allows for quoted strings
+ * and escaped characters.
+ *
+ * It returns the string (or NULL, if *stringp is NULL),
+ * which is a de-quoted version of the string if necessary.
+ *
+ * It modifies *stringp in place.
+ */
+static char *
+strsep_quote(char **stringp, const char *delim)
+{
+	char *srcptr, *dstptr, *retval;
+	char quot = 0;
+	
+	if (stringp == NULL || *stringp == NULL)
+		return (NULL);
+
+	srcptr = dstptr = retval = *stringp;
+
+	while (*srcptr) {
+		/*
+		 * We're looking for several edge cases here.
+		 * First:  if we're in quote state (quot != 0),
+		 * then we ignore the delim characters, but otherwise
+		 * process as normal, unless it is the quote character.
+		 * Second:  if the current character is a backslash,
+		 * we take the next character as-is, without checking
+		 * for delim, quote, or backslash.  Exception:  if the
+		 * next character is a NUL, that's the end of the string.
+		 * Third:  if the character is a quote character, we toggle
+		 * quote state.
+		 * Otherwise:  check the current character for NUL, or
+		 * being in delim, and end the string if either is true.
+		 */
+		if (*srcptr == '\\') {
+			srcptr++;
+			/*
+			 * The edge case here is if the next character
+			 * is NUL, we want to stop processing.  But if
+			 * it's not NUL, then we simply want to copy it.
+			 */
+			if (*srcptr) {
+				*dstptr++ = *srcptr++;
+			}
+			continue;
+		}
+		if (quot == 0 && (*srcptr == '\'' || *srcptr == '"')) {
+			quot = *srcptr++;
+			continue;
+		}
+		if (quot && *srcptr == quot) {
+			/* End of the quoted part */
+			quot = 0;
+			srcptr++;
+			continue;
+		}
+		if (!quot && strchr(delim, *srcptr))
+			break;
+		*dstptr++ = *srcptr++;
+	}
+
+	*dstptr = 0; /* Terminate the string */
+	*stringp = (*srcptr == '\0') ? NULL : srcptr + 1;
+	return (retval);
+}
+
+/*
  * Mountd server for NFS mount protocol as described in:
  * NFS: Network File System Protocol Specification, RFC1094, Appendix A
  * The optional arguments are the exports file name
@@ -2849,8 +2917,9 @@ parsecred(char *namelist, struct xucred 
 	/*
 	 * Get the user's password table entry.
 	 */
-	names = strsep(&namelist, " \t\n");
+	names = strsep_quote(&namelist, " \t\n");
 	name = strsep(&names, ":");
+	/* Bug?  name could be NULL here */
 	if (isdigit(*name) || *name == '-')
 		pw = getpwuid(atoi(name));
 	else


More information about the svn-src-all mailing list