Support only splitting users/groups on commas.
authorWayne Davison <wayned@samba.org>
Sun, 17 Apr 2016 22:53:11 +0000 (15:53 -0700)
committerWayne Davison <wayned@samba.org>
Sun, 17 Apr 2016 22:56:11 +0000 (15:56 -0700)
Fixes bug 11817.

clientserver.c
rsyncd.conf.yo
util.c

index 27f8cd38b737d29e0ef30daf77d05ee99b4c59c0..91aee27088c158583f7e3da50b196d9f8204cbd3 100644 (file)
@@ -592,7 +592,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        } else
                set_uid = 0;
 
-       p = *lp_gid(i) ? strtok(lp_gid(i), ", ") : NULL;
+       p = *lp_gid(i) ? conf_strtok(lp_gid(i)) : NULL;
        if (p) {
                /* The "*" gid must be the first item in the list. */
                if (strcmp(p, "*") == 0) {
@@ -609,7 +609,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
 #endif
                } else if (add_a_group(f_out, p) < 0)
                        return -1;
-               while ((p = strtok(NULL, ", ")) != NULL) {
+               while ((p = conf_strtok(NULL)) != NULL) {
 #if defined HAVE_INITGROUPS && !defined HAVE_GETGROUPLIST
                        if (pw) {
                                rprintf(FLOG, "This rsync cannot add groups after \"*\".\n");
index 5c78b0add3e4d2df51620bb674a7e82e338d1a81..1813354bd9461781f4b7a743722ef1b78ca56d6b 100644 (file)
@@ -492,6 +492,13 @@ group "guest").  Any other user who is in group "rsync" will get read-only
 access.  Finally, users susan, joe, and sam get the ro/rw setting of the
 module, but only if the user didn't match an earlier group-matching rule.
 
+If you need to specify a user or group name with a space in it, start your list
+with a comma to indicate that the list should only be split on commas (though
+leading and trailing whitespace will also be removed, and empty entries are
+just ignored).  For example:
+
+verb(  auth users = , joe:deny, @Some Group:deny, admin:rw, @RO Group:ro )
+
 See the description of the secrets file for how you can have per-user passwords
 as well as per-group passwords.  It also explains how a user can authenticate
 using their user password or (when applicable) a group password, depending on
@@ -534,9 +541,9 @@ than the one that the rsync daemon is running under.  If "strict modes" is
 false, the check is not performed.  The default is true.  This parameter
 was added to accommodate rsync running on the Windows operating system.
 
-dit(bf(hosts allow)) This parameter allows you to specify a
-list of patterns that are matched against a connecting clients
-hostname and IP address. If none of the patterns match then the
+dit(bf(hosts allow)) This parameter allows you to specify a list of comma-
+and/or whitespace-separated patterns that are matched against a connecting
+client's hostname and IP address.  If none of the patterns match, then the
 connection is rejected.
 
 Each pattern can be in one of five forms:
@@ -580,9 +587,9 @@ connect.
 
 The default is no "hosts allow" parameter, which means all hosts can connect.
 
-dit(bf(hosts deny)) This parameter allows you to specify a
-list of patterns that are matched against a connecting clients
-hostname and IP address. If the pattern matches then the connection is
+dit(bf(hosts deny)) This parameter allows you to specify a list of comma-
+and/or whitespace-separated patterns that are matched against a connecting
+clients hostname and IP address. If the pattern matches then the connection is
 rejected. See the "hosts allow" parameter for more information.
 
 The default is no "hosts deny" parameter, which means all hosts can connect.
diff --git a/util.c b/util.c
index 2a3e5ba98c113f3dce5010c37da989122cbeea22..ca38f3ea0f97e657eec2f7fe53e7ebd1f640c614 100644 (file)
--- a/util.c
+++ b/util.c
@@ -800,6 +800,41 @@ void strlower(char *s)
        }
 }
 
+/**
+ * Split a string into tokens based (usually) on whitespace & commas.  If the
+ * string starts with a comma (after skipping any leading whitespace), then
+ * splitting is done only on commas. No empty tokens are ever returned. */
+char *conf_strtok(char *str)
+{
+       static int commas_only = 0;
+
+       if (str) {
+               while (isSpace(str)) str++;
+               if (*str == ',') {
+                       commas_only = 1;
+                       str++;
+               } else
+                       commas_only = 0;
+       }
+
+       while (commas_only) {
+               char *end, *tok = strtok(str, ",");
+               if (!tok)
+                       return NULL;
+               /* Trim just leading and trailing whitespace. */
+               while (isSpace(tok))
+                       tok++;
+               end = tok + strlen(tok);
+               while (end > tok && isSpace(end-1))
+                       *--end = '\0';
+               if (*tok)
+                       return tok;
+               str = NULL;
+       }
+
+       return strtok(str, " ,\t\r\n");
+}
+
 /* Join strings p1 & p2 into "dest" with a guaranteed '/' between them.  (If
  * p1 ends with a '/', no extra '/' is inserted.)  Returns the length of both
  * strings + 1 (if '/' was inserted), regardless of whether the null-terminated