summaryrefslogtreecommitdiffstats
path: root/usr.sbin/mountd/mountd.c
diff options
context:
space:
mode:
authorgjb <gjb@FreeBSD.org>2016-01-07 17:23:43 +0000
committergjb <gjb@FreeBSD.org>2016-01-07 17:23:43 +0000
commit46171d6b451918f84a7cd081856fd46d1e0a36d6 (patch)
tree1b5c54521eb34f18633fcc07d841cdd8052d7440 /usr.sbin/mountd/mountd.c
parent520e1515a8cbcd1db17e1b5c4042641fba3c9976 (diff)
parentf7dfde9b82551989ae798ddbf91a0baab930dad0 (diff)
downloadFreeBSD-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.c71
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
OpenPOWER on IntegriCloud