From: Wayne Davison Date: Sun, 17 Apr 2016 22:53:11 +0000 (-0700) Subject: Support only splitting users/groups on commas. X-Git-Tag: v3.1.3pre1~50 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a12959ab6017a859fe8cd90ae2043b62a85b306;p=thirdparty%2Frsync.git Support only splitting users/groups on commas. Fixes bug 11817. --- diff --git a/clientserver.c b/clientserver.c index 27f8cd38..91aee270 100644 --- a/clientserver.c +++ b/clientserver.c @@ -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"); diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo index 5c78b0ad..1813354b 100644 --- a/rsyncd.conf.yo +++ b/rsyncd.conf.yo @@ -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 2a3e5ba9..ca38f3ea 100644 --- 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