[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Tue Sep 13 05:06:41 UTC 2022


The branch, master has been updated
       via  51dae12c Update NEWS.
       via  95073031 Fix bug with validing remote filter rules.
       via  81c5c813 Mention the filename when unpack_smb_acl() returns an error.
       via  a6a0d2f7 Require a newer protocol to specify the digest list.
       via  418e38a8 Talk about the new daemon greeting line.
       via  b2dcabdb Improve output of "N-bit" items in json data.
      from  ad53a9b5 Also change dashes in the dict var names to make jq use easier.

https://git.samba.org/?p=rsync.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 51dae12c929d55cf4d5eb95c088910342809bcc5
Author: Wayne Davison <wayne at opencoder.net>
Date:   Mon Sep 12 22:04:33 2022 -0700

    Update NEWS.

commit 950730313de994d191ba2d5be575e97690b355e8
Author: Wayne Davison <wayne at opencoder.net>
Date:   Mon Sep 12 22:02:00 2022 -0700

    Fix bug with validing remote filter rules.

commit 81c5c81381d86d84fca3a2681ad0c2027bc65d6e
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sun Sep 11 10:03:16 2022 -0700

    Mention the filename when unpack_smb_acl() returns an error.

commit a6a0d2f77c7d1f06829c301914585a3d873fcd39
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sat Sep 10 21:52:54 2022 -0700

    Require a newer protocol to specify the digest list.

commit 418e38a8789fd9b668961f945382c78806f2fb20
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sat Sep 10 21:30:46 2022 -0700

    Talk about the new daemon greeting line.

commit b2dcabdbb9a50074655bd731425c13cea5874c76
Author: Wayne Davison <wayne at opencoder.net>
Date:   Sat Sep 10 21:05:07 2022 -0700

    Improve output of "N-bit" items in json data.

-----------------------------------------------------------------------

Summary of changes:
 NEWS.md                    |  4 +++-
 acls.c                     |  1 +
 clientserver.c             | 12 ++++++++---
 csprotocol.txt             | 52 ++++++++++++++++++++++++++++++++--------------
 exclude.c                  | 35 ++++++++++++++++++-------------
 flist.c                    |  2 +-
 rsync.h                    |  1 +
 support/json-rsync-version | 13 ++++++++----
 usage.c                    | 11 +++++++---
 9 files changed, 89 insertions(+), 42 deletions(-)


Changeset truncated at 500 lines:

diff --git a/NEWS.md b/NEWS.md
index fe962ad0..44eddd9b 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -4,7 +4,9 @@
 
 ### BUG FIXES:
 
-- ...
+- Fix a bug with validating remote filter rules.
+
+- When rsync gets and unpack error on an ACL, mention the filename.
 
 ### ENHANCEMENTS:
 
diff --git a/acls.c b/acls.c
index 12e662cf..3cf12eeb 100644
--- a/acls.c
+++ b/acls.c
@@ -519,6 +519,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl,
 
 		sys_acl_free_acl(sacl);
 		if (!ok) {
+			rsyserr(FERROR_XFER, errno, "get_acl: unpack_smb_acl(%s)", fname);
 			return -1;
 		}
 	} else if (no_acl_syscall_error(errno)) {
diff --git a/clientserver.c b/clientserver.c
index 7436d01e..9ad7eaf7 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -184,11 +184,11 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
 	}
 
 	if (remote_sub < 0) {
-		if (remote_protocol == 30) {
+		if (remote_protocol >= 30) {
 			if (am_client)
-				rprintf(FERROR, "rsync: server is speaking an incompatible beta of protocol 30\n");
+				rprintf(FERROR, "rsync: the server omitted the subprotocol value: %s\n", buf);
 			else
-				io_printf(f_out, "@ERROR: your client is speaking an incompatible beta of protocol 30\n");
+				io_printf(f_out, "@ERROR: your client omitted the subprotocol value: %s\n", buf);
 			return -1;
 		}
 		remote_sub = 0;
@@ -200,6 +200,12 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int
 		daemon_auth_choices = strdup(daemon_auth_choices + 1);
 		if ((cp = strchr(daemon_auth_choices, '\n')) != NULL)
 			*cp = '\0';
+	} else if (remote_protocol > 31) {
+		if (am_client)
+			rprintf(FERROR, "rsync: the server omitted the digest name list: %s\n", buf);
+		else
+			io_printf(f_out, "@ERROR: your client omitted the digest name list: %s\n", buf);
+		return -1;
 	}
 
 	if (protocol_version > remote_protocol) {
diff --git a/csprotocol.txt b/csprotocol.txt
index c8dadd41..4c7ec5b8 100644
--- a/csprotocol.txt
+++ b/csprotocol.txt
@@ -7,39 +7,54 @@ basically a summary of clientserver.c and authenticate.c.
 This is the protocol used for rsync --daemon; i.e. connections to port
 873 rather than invocations over a remote shell.
 
-When the server accepts a connection, it prints a greeting
+When the server accepts a connection, it prints a newline-terminated
+greeting line:
 
-  @RSYNCD: <version>.<subprotocol>
+  @RSYNCD: <version>.<subprotocol> <digest1> <digestN>
 
-where <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
-'.' is a literal period, and <subprotocol> is the numeric subprotocol
-version (see SUBPROTOCOL_VERSION -- it will be 0 for final releases).
-Protocols prior to 30 only output <version> alone.  The daemon expects
-to see a similar greeting back from the client.  For protocols prior to
-30, an absent ".<subprotocol>" value is assumed to be 0.  For protocol
-30, an absent value is a fatal error.  The daemon then follows this line
-with a free-format text message-of-the-day (if any is defined).
+The <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
+The <subprotocol> is the numeric subprotocol version (which is 0 for a
+final protocol version, as the SUBPROTOCOL_VERSION define discusses).
+The <digestN> names are the authentication digest algorithms that the
+daemon supports, listed in order of preference.
+
+An rsync prior to 3.2.7 omits the digest names.  An rsync prior to 3.0.0
+also omits the period and the <subprotocol> value.  Since a final
+protocol has a subprotocol value of 0, a missing subprotocol value is
+assumed to be 0 for any protocol prior to 30.  It is considered a fatal
+error for protocol 30 and above to omit it.  It is considered a fatal
+error for protocol 32 and above to omit the digest name list (currently
+31 is the newest protocol).
+
+The daemon expects to see a similar greeting line back from the client.
+Once received, the daemon follows the opening line with a free-format
+text message-of-the-day (if any is defined).
 
 The server is now in the connected state.  The client can either send
-the command
+the command:
 
   #list
 
-to get a listing of modules, or the name of a module.  After this, the
+(to get a listing of modules) or the name of a module.  After this, the
 connection is now bound to a particular module.  Access per host for
 this module is now checked, as is per-module connection limits.
 
-If authentication is required to use this module, the server will say
+If authentication is required to use this module, the server will say:
 
   @RSYNCD: AUTHREQD <challenge>
 
 where <challenge> is a random string of base64 characters.  The client
-must respond with
+must respond with:
 
   <user> <response>
 
-where <user> is the username they claim to be, and <response> is the
-base64 form of the MD4 hash of challenge+password.
+The <user> is the username they claim to be. The <response> is the
+base64 form of the digest hash of the challenge+password string. The
+chosen digest method is the most preferred client method that is also in
+the server's list.  If no digest list was explicitly provided, the side
+expecting a list assumes the other side provided either the single name
+"md5" (for a negotiated protocol 30), or the single name "md4" (for an
+older protocol).
 
 At this point the server applies all remaining constraints before
 handing control to the client, including switching uid/gid, setting up
@@ -76,6 +91,11 @@ stay tuned (or write it yourself!).
 ------------
 Protocol version changes
 
+31	(2022-09-10, 3.2.7dev)
+
+	The use of a suffixed list of digest names was added as an
+	optional suffix to the greeting line.
+
 30	(2007-10-04, 3.0.0pre1)
 
 	The use of a ".<subprotocol>" number was added to
diff --git a/exclude.c b/exclude.c
index 5458455b..4022e824 100644
--- a/exclude.c
+++ b/exclude.c
@@ -78,6 +78,10 @@ static filter_rule **mergelist_parents;
 static int mergelist_cnt = 0;
 static int mergelist_size = 0;
 
+#define LOCAL_RULE   1
+#define REMOTE_RULE  2
+static uchar cur_elide_value = REMOTE_RULE;
+
 /* Each filter_list_struct describes a singly-linked list by keeping track
  * of both the head and tail pointers.  The list is slightly unusual in that
  * a parent-dir's content can be appended to the end of the local list in a
@@ -220,6 +224,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_
 				slash_cnt++;
 		}
 	}
+	rule->elide = 0;
 	strlcpy(rule->pattern + pre_len, pat, pat_len + 1);
 	pat_len += pre_len;
 	if (suf_len) {
@@ -900,7 +905,7 @@ static int rule_matches(const char *fname, filter_rule *ex, int name_flags)
 	const char *strings[16]; /* more than enough */
 	const char *name = fname + (*fname == '/');
 
-	if (!*name)
+	if (!*name || ex->elide == cur_elide_value)
 		return 0;
 
 	if (!(name_flags & NAME_IS_XATTR) ^ !(ex->rflags & FILTRULE_XATTR))
@@ -1016,6 +1021,15 @@ int name_is_excluded(const char *fname, int name_flags, int filter_level)
 	return 0;
 }
 
+int check_server_filter(filter_rule_list *listp, enum logcode code, const char *name, int name_flags)
+{
+	int ret;
+	cur_elide_value = LOCAL_RULE;
+	ret = check_filter(listp, code, name, name_flags);
+	cur_elide_value = REMOTE_RULE;
+	return ret;
+}
+
 /* Return -1 if file "name" is defined to be excluded by the specified
  * exclude list, 1 if it is included, and 0 if it was not matched. */
 int check_filter(filter_rule_list *listp, enum logcode code,
@@ -1571,7 +1585,7 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer,
 
 static void send_rules(int f_out, filter_rule_list *flp)
 {
-	filter_rule *ent, *prev = NULL;
+	filter_rule *ent;
 
 	for (ent = flp->head; ent; ent = ent->next) {
 		unsigned int len, plen, dlen;
@@ -1586,21 +1600,15 @@ static void send_rules(int f_out, filter_rule_list *flp)
 		 * merge files as an optimization (since they can only have
 		 * include/exclude rules). */
 		if (ent->rflags & FILTRULE_SENDER_SIDE)
-			elide = am_sender ? 1 : -1;
+			elide = am_sender ? LOCAL_RULE : REMOTE_RULE;
 		if (ent->rflags & FILTRULE_RECEIVER_SIDE)
-			elide = elide ? 0 : am_sender ? -1 : 1;
+			elide = elide ? 0 : am_sender ? REMOTE_RULE : LOCAL_RULE;
 		else if (delete_excluded && !elide
 		 && (!(ent->rflags & FILTRULE_PERDIR_MERGE)
 		  || ent->rflags & FILTRULE_NO_PREFIXES))
-			elide = am_sender ? 1 : -1;
-		if (elide < 0) {
-			if (prev)
-				prev->next = ent->next;
-			else
-				flp->head = ent->next;
-		} else
-			prev = ent;
-		if (elide > 0)
+			elide = am_sender ? LOCAL_RULE : REMOTE_RULE;
+		ent->elide = elide;
+		if (elide == LOCAL_RULE)
 			continue;
 		if (ent->rflags & FILTRULE_CVS_IGNORE
 		    && !(ent->rflags & FILTRULE_MERGE_FILE)) {
@@ -1628,7 +1636,6 @@ static void send_rules(int f_out, filter_rule_list *flp)
 		if (dlen)
 			write_byte(f_out, '/');
 	}
-	flp->tail = prev;
 }
 
 /* This is only called by the client. */
diff --git a/flist.c b/flist.c
index 0313db54..db11b353 100644
--- a/flist.c
+++ b/flist.c
@@ -991,7 +991,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
 	if (*thisname != '.' || thisname[1] != '\0') {
 		int filt_flags = S_ISDIR(mode) ? NAME_IS_DIR : NAME_IS_FILE;
 		if (!trust_sender_filter /* a per-dir filter rule means we must trust the sender's filtering */
-		 && filter_list.head && check_filter(&filter_list, FINFO, thisname, filt_flags) < 0) {
+		 && filter_list.head && check_server_filter(&filter_list, FINFO, thisname, filt_flags) < 0) {
 			rprintf(FERROR, "ERROR: rejecting excluded file-list name: %s\n", thisname);
 			exit_cleanup(RERR_PROTOCOL);
 		}
diff --git a/rsync.h b/rsync.h
index f0d3dd0b..0a5ff809 100644
--- a/rsync.h
+++ b/rsync.h
@@ -1024,6 +1024,7 @@ typedef struct filter_struct {
 		int slash_cnt;
 		struct filter_list_struct *mergelist;
 	} u;
+	uchar elide;
 } filter_rule;
 
 typedef struct filter_list_struct {
diff --git a/support/json-rsync-version b/support/json-rsync-version
index afaf7382..a51c3a88 100755
--- a/support/json-rsync-version
+++ b/support/json-rsync-version
@@ -35,13 +35,18 @@ def main():
                 for x in line.strip(' ,').split(', '):
                     if ' ' in x:
                         val, var = x.split(' ', 1)
+                        if val == 'no':
+                            val = False
+                        elif val.endswith('-bit'):
+                            var = var[:-1] + '_bits'
+                            val = int(val.split('-')[0])
                         if var == 'protect-args':
                             var = 'secluded-args'
-                        var = var.replace(' ', '_').replace('-', '_')
-                        info[sect_name][var] = False if val == 'no' else val
                     else:
-                        x = x.replace('-', '_')
-                        info[sect_name][x] = True
+                        var = x
+                        val = True
+                    var = var.replace(' ', '_').replace('-', '_')
+                    info[sect_name][var] = val
             else:
                 info[sect_name] += [ x for x in line.split() if not x.startswith('(') ]
         elif line == '':
diff --git a/usage.c b/usage.c
index a2c2a3f0..7f215a02 100644
--- a/usage.c
+++ b/usage.c
@@ -172,13 +172,18 @@ static void print_info_flags(enum logcode f)
 		else if (as_json) {
 			char *space = strchr(str, ' ');
 			int is_no = space && strncmp(str, "no ", 3) == 0;
-			char *quot = space && !is_no ? "\"" : "";
+			int is_bits = space && isDigit(str);
+			char *quot = space && !is_no && !is_bits ? "\"" : "";
 			char *item = space ? space + 1 : str;
 			char *val = !space ? "true" : is_no ? "false" : str;
 			int val_len = !space ? 4 : is_no ? 5 : space - str;
+			if (is_bits && (space = strchr(val, '-')) != NULL)
+			    val_len = space - str;
 			item_len = snprintf(item_buf, sizeof item_buf,
-					   " \"%s\": %s%.*s%s%s", item, quot, val_len, val, quot,
-					   need_comma ? "," : "");
+					   " \"%s%s\": %s%.*s%s%s", item, is_bits ? "bits" : "",
+					   quot, val_len, val, quot, need_comma ? "," : "");
+			if (is_bits)
+				item_buf[strlen(item)+2-1] = '_'; /* Turn the 's' into a '_' */
 			for (space = item; (space = strpbrk(space, " -")) != NULL; space++)
 				item_buf[space - item + 2] = '_';
 		} else


-- 
The rsync repository.



More information about the rsync-cvs mailing list