diff options
author | jpaetzel <jpaetzel@FreeBSD.org> | 2016-01-16 01:40:46 +0000 |
---|---|---|
committer | jpaetzel <jpaetzel@FreeBSD.org> | 2016-01-16 01:40:46 +0000 |
commit | f7e7eb71bece1f4b40dd4f81ec39a639522a5793 (patch) | |
tree | a3fe94569574eafdb40c7181116d717d4607d060 /usr.sbin | |
parent | 778aaf99e64d2edf840afe7641ee3ee4a4a7bb52 (diff) | |
download | FreeBSD-src-f7e7eb71bece1f4b40dd4f81ec39a639522a5793.zip FreeBSD-src-f7e7eb71bece1f4b40dd4f81ec39a639522a5793.tar.gz |
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
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/mountd/exports.5 | 2 | ||||
-rw-r--r-- | usr.sbin/mountd/mountd.c | 71 |
2 files changed, 72 insertions, 1 deletions
diff --git a/usr.sbin/mountd/exports.5 b/usr.sbin/mountd/exports.5 index 88e2219..018a865 100644 --- a/usr.sbin/mountd/exports.5 +++ b/usr.sbin/mountd/exports.5 @@ -131,6 +131,7 @@ The credential includes all the groups to which the user is a member 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 diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 7582195..89c7afb 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -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 *cr) /* * 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 |