Do we need excluded_below?
Wayne Davison
wayned at samba.org
Fri Mar 21 23:00:40 GMT 2008
On Tue, Mar 18, 2008 at 03:11:06PM -0400, Matt McCutchen wrote:
> rsync-dev -r -vi rsync://user@localhost:3141/module/./secret/ download/
This is now fixed.
> rsync-dev -r -vi --files-from=<(echo secret/) --no-R rsync://user@localhost:3141/module/ download/
I can think of 3 different ways to deal with this. (1) Don't do
anything, since a daemon exclude should be using a dir/*** rule. (2)
add path-checking to the file-from arg-reading code, so that every dir
is compared against the exclude list. (3) Try to get fancy and enhance
an absolute exclude of a directory (whose rule does not have "**" in it
anywhere) to add a rule that excludes each found directory using a
dir/*** rule. I coded up the latter, and it passes some basic tests
(diff attached).
Thoughts?
> BTW, what is the purpose of leaving the path truncated in
> "filter_server_path"?
Returning an arg that is known to match a daemon exclude ensures that it
will be excluded by the code that parses the args. If the exclude was a
dir/*** exclude, we could return back the non-truncated arg.
> This makes it possible to distinguish between a nonexistent and
> daemon-excluded dir /secret by trying to pull /secret/X/ and seeing
> whether the path in the error message is truncated.
I've always seen the path truncated in the error, but the error is
sometimes inconsistent. I.e. a really non-existent directory in a path
sometimes returns a push_dir failure, while the (current) code that
rejects an excluded dir always returns a file-not-found error. It may
be possible to further conceal this.
..wayne..
-------------- next part --------------
--- a/clientserver.c
+++ b/clientserver.c
@@ -699,6 +699,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
}
}
+ enhance_daemon_excludes();
+
if (am_root) {
/* XXXX: You could argue that if the daemon is started
* by a non-root user and they explicitly specify a
--- a/exclude.c
+++ b/exclude.c
@@ -651,6 +651,63 @@ int check_filter(struct filter_list_struct *listp, const char *name, int name_is
return 0;
}
+/* If an absolute exclude w/o a ** matches a dir, add a trailing slash+***
+ * rule to ensure that the dir's contents stays excluded. */
+int enhance_daemon_excludes(void)
+{
+ struct filter_struct **our_ex_p, *ex, *add, *save = daemon_filter_list.head;
+ int len, argc = 0, maxargs = 0;
+ char *cp, buf[MAXPATHLEN+4], **argv = NULL;
+
+ /* Disable the excludes for our use of glob_expand(). */
+ daemon_filter_list.head = NULL;
+
+ for (our_ex_p = &save; (ex = *our_ex_p) != NULL; our_ex_p = &ex->next) {
+ if (ex->match_flags & (MATCHFLG_WILD2|MATCHFLG_INCLUDE|MATCHFLG_MERGE_FILE|MATCHFLG_PERDIR_MERGE)
+ || ex->pattern[0] != '/'
+ || (len = strlcpy(buf, ex->pattern, MAXPATHLEN)) >= MAXPATHLEN)
+ continue;
+ /* We want to find just dirs that match this absolute exclude,
+ * which we can do by adding a trailing "/." -- but, we also
+ * want room to add more chars, so use "/./." instead. */
+ if (buf[len-1] != '/')
+ buf[len++] = '/';
+ buf[len++] = '.';
+ buf[len++] = '/';
+ buf[len++] = '.';
+ buf[len] = '\0';
+ argc = 0;
+ if (!glob_expand(buf, &argv, &argc, &maxargs)) {
+ free(argv[0]); /* dump strdup of failed glob string */
+ continue;
+ }
+ while (argc) {
+ if (!(add = new0(struct filter_struct)))
+ out_of_memory("enhance_daemon_excludes");
+ add->pattern = argv[--argc];
+ len = strlen(add->pattern);
+ /* Patterns come back w/o leading slash. */
+ memmove(add->pattern+1, add->pattern, len - 3);
+ /* Use 3-char "./." suffix's space to add back "/"
+ * prefix and a "**" suffix (flagged as "***"). */
+ add->pattern[0] = '/';
+ add->pattern[len-1] = add->pattern[len-2] = '*';
+ add->match_flags = ex->match_flags|MATCHFLG_WILD|MATCHFLG_WILD2|MATCHFLG_WILD3_SUFFIX;
+ for (cp = add->pattern; (cp = strchr(cp, '/')) != NULL; cp++)
+ add->u.slash_cnt++;
+ add->next = ex;
+ *our_ex_p = add;
+ our_ex_p = &add->next;
+ }
+ }
+
+ glob_expand(NULL, NULL, NULL, NULL);
+
+ daemon_filter_list.head = save;
+
+ return 0;
+}
+
#define RULE_STRCMP(s,r) rule_strcmp((s), (r), sizeof (r) - 1)
static const uchar *rule_strcmp(const uchar *str, const char *rule, int rule_len)
More information about the rsync
mailing list