Date: Sat, 16 Jan 2016 01:40:46 +0000 (UTC) From: Josh Paetzel <jpaetzel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294124 - stable/10/usr.sbin/mountd Message-ID: <201601160140.u0G1ekH8055988@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601160140.u0G1ekH8055988>