diff options
author | gjb <gjb@FreeBSD.org> | 2016-01-07 17:23:43 +0000 |
---|---|---|
committer | gjb <gjb@FreeBSD.org> | 2016-01-07 17:23:43 +0000 |
commit | 46171d6b451918f84a7cd081856fd46d1e0a36d6 (patch) | |
tree | 1b5c54521eb34f18633fcc07d841cdd8052d7440 /usr.sbin/mountd/mountd.c | |
parent | 520e1515a8cbcd1db17e1b5c4042641fba3c9976 (diff) | |
parent | f7dfde9b82551989ae798ddbf91a0baab930dad0 (diff) | |
download | FreeBSD-src-46171d6b451918f84a7cd081856fd46d1e0a36d6.zip FreeBSD-src-46171d6b451918f84a7cd081856fd46d1e0a36d6.tar.gz |
MFH
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'usr.sbin/mountd/mountd.c')
-rw-r--r-- | usr.sbin/mountd/mountd.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 535a3f7..d6da2bc 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -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 *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 |