Date: Thu, 7 Jan 2016 05:34:39 +0000 (UTC) From: Josh Paetzel <jpaetzel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293305 - head/usr.sbin/mountd Message-ID: <201601070534.u075Yd85056890@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601070534.u075Yd85056890>