Author: jpaetzel
Date: Thu Jan  7 05:34:39 2016
New Revision: 293305
URL: https://svnweb.freebsd.org/changeset/base/293305

Log:
  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
  MFC after:    1 week
  Sponsored by: iXsystems

Modified:
  head/usr.sbin/mountd/exports.5
  head/usr.sbin/mountd/mountd.c

Modified: head/usr.sbin/mountd/exports.5
==============================================================================
--- head/usr.sbin/mountd/exports.5      Thu Jan  7 04:02:37 2016        
(r293304)
+++ head/usr.sbin/mountd/exports.5      Thu Jan  7 05:34:39 2016        
(r293305)
@@ -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: head/usr.sbin/mountd/mountd.c
==============================================================================
--- head/usr.sbin/mountd/mountd.c       Thu Jan  7 04:02:37 2016        
(r293304)
+++ head/usr.sbin/mountd/mountd.c       Thu Jan  7 05:34:39 2016        
(r293305)
@@ -174,6 +174,7 @@ static int  check_options(struct dirlist 
 static int     checkmask(struct sockaddr *sa);
 static 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 @@ static 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
@@ -2831,8 +2899,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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to