summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjpaetzel <jpaetzel@FreeBSD.org>2016-01-07 05:34:39 +0000
committerjpaetzel <jpaetzel@FreeBSD.org>2016-01-07 05:34:39 +0000
commit57f950f66144ba13aa49313465c1a278e1268cbc (patch)
treed02b78d23d4cc6ff5acb62d5e897483a50d59408
parentcbad85009dc5a9ad56a8247e468426907bb9e600 (diff)
downloadFreeBSD-src-57f950f66144ba13aa49313465c1a278e1268cbc.zip
FreeBSD-src-57f950f66144ba13aa49313465c1a278e1268cbc.tar.gz
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
-rw-r--r--usr.sbin/mountd/exports.52
-rw-r--r--usr.sbin/mountd/mountd.c71
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 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