/* * Copyright (C) 1996, 2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> * Copyright (C) 2003-2022 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, visit the http://fsf.org website. */ #define False 0#define True 1#define Unset (-1) /* Our BOOL values are always an int. */ #define BLOCK_SIZE 700#define RSYNC_RSH_ENV "RSYNC_RSH"#define RSYNC_RSH_IO_ENV "RSYNC_RSH_IO" #define RSYNC_NAME "rsync"/* RSYNCD_SYSCONF is now set in config.h */#define RSYNCD_USERCONF "rsyncd.conf" #define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"#define URL_PREFIX "rsync://" #define SYMLINK_PREFIX "/rsyncd-munged/" /* This MUST have a trailing slash! */#define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1) #define BACKUP_SUFFIX "~" /* a non-zero CHAR_OFFSET makes the rolling sum stronger, but is incompatible with older versions :-( */#define CHAR_OFFSET 0 /* These flags are only used during the flist transfer. */ #define XMIT_TOP_DIR (1<<0)#define XMIT_SAME_MODE (1<<1)#define XMIT_SAME_RDEV_pre28 (1<<2) /* protocols 20 - 27 */#define XMIT_EXTENDED_FLAGS (1<<2) /* protocols 28 - now */#define XMIT_SAME_UID (1<<3)#define XMIT_SAME_GID (1<<4)#define XMIT_SAME_NAME (1<<5)#define XMIT_LONG_NAME (1<<6)#define XMIT_SAME_TIME (1<<7) #define XMIT_SAME_RDEV_MAJOR (1<<8) /* protocols 28 - now (devices only) */#define XMIT_NO_CONTENT_DIR (1<<8) /* protocols 30 - now (dirs only) */#define XMIT_HLINKED (1<<9) /* protocols 28 - now (non-dirs) */#define XMIT_SAME_DEV_pre30 (1<<10) /* protocols 28 - 29 */#define XMIT_USER_NAME_FOLLOWS (1<<10) /* protocols 30 - now */#define XMIT_RDEV_MINOR_8_pre30 (1<<11) /* protocols 28 - 29 */#define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */#define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - now (HLINKED files only) */#define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31*- now (w/XMIT_EXTENDED_FLAGS) (also protocol 30 w/'f' compat flag) */#define XMIT_MOD_NSEC (1<<13) /* protocols 31 - now */#define XMIT_SAME_ATIME (1<<14) /* any protocol - restricted by command-line option */#define XMIT_UNUSED_15 (1<<15) /* unused flag bit */ /* The following XMIT flags require an rsync that uses a varint for the flag values */ #define XMIT_RESERVED_16 (1<<16) /* reserved for future fileflags use */#define XMIT_CRTIME_EQ_MTIME (1<<17) /* any protocol - restricted by command-line option */ /* These flags are used in the live flist data. */ #define FLAG_TOP_DIR (1<<0) /* sender/receiver/generator */#define FLAG_OWNED_BY_US (1<<0) /* generator: set by make_file() for aux flists only */#define FLAG_FILE_SENT (1<<1) /* sender/receiver/generator */#define FLAG_DIR_CREATED (1<<1) /* generator */#define FLAG_CONTENT_DIR (1<<2) /* sender/receiver/generator */#define FLAG_MOUNT_DIR (1<<3) /* sender/generator (dirs only) */#define FLAG_SKIP_HLINK (1<<3) /* receiver/generator (w/FLAG_HLINKED) */#define FLAG_DUPLICATE (1<<4) /* sender */#define FLAG_MISSING_DIR (1<<4) /* generator */#define FLAG_HLINKED (1<<5) /* receiver/generator (checked on all types) */#define FLAG_HLINK_FIRST (1<<6) /* receiver/generator (w/FLAG_HLINKED) */#define FLAG_IMPLIED_DIR (1<<6) /* sender/receiver/generator (dirs only) */#define FLAG_HLINK_LAST (1<<7) /* receiver/generator */#define FLAG_HLINK_DONE (1<<8) /* receiver/generator (checked on all types) */#define FLAG_LENGTH64 (1<<9) /* sender/receiver/generator */#define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */#define FLAG_TIME_FAILED (1<<11)/* generator */#define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */#define FLAG_GOT_DIR_FLIST (1<<13)/* sender/receiver/generator - dir_flist only */ /* These flags are passed to functions but not stored. */ #define FLAG_DIVERT_DIRS (1<<16) /* sender, but must be unique */#define FLAG_PERHAPS_DIR (1<<17) /* generator */ /* These flags are for get_dirlist(). */#define GDL_IGNORE_FILTER_RULES (1<<0)#define GDL_PERHAPS_DIR (1<<1) /* Some helper macros for matching bits. */#define BITS_SET(val,bits) (((val) & (bits)) == (bits))#define BITS_SETnUNSET(val,onbits,offbits) (((val) & ((onbits)|(offbits))) == (onbits))#define BITS_EQUAL(b1,b2,mask) (((unsigned)(b1) & (unsigned)(mask)) \ == ((unsigned)(b2) & (unsigned)(mask))) /* Update this if you make incompatible changes and ALSO update the * SUBPROTOCOL_VERSION if it is not a final (official) release. */#define PROTOCOL_VERSION 32 /* This is used when working on a new protocol version or for any unofficial * protocol tweaks. It should be a non-zero value for each pre-release repo * change that affects the protocol. The official pre-release versions should * start with 1 (after incrementing the PROTOCOL_VERSION) and go up by 1 for * each new protocol change. For unofficial changes, pick a fairly large * random number that will hopefully not collide with anyone else's unofficial * protocol. It must ALWAYS be 0 when the protocol goes final (and official) * and NEVER before! When rsync negotiates a protocol match, it will only * allow the newest protocol to be used if the SUBPROTOCOL_VERSION matches. * All older protocol versions MUST be compatible with the final, official * release of the protocol, so don't tweak the code to change the protocol * behavior for an older protocol version. */#define SUBPROTOCOL_VERSION 0 /* We refuse to interoperate with versions that are not in this range. * Note that we assume we'll work with later versions: the onus is on * people writing them to make sure that they don't send us anything * we won't understand. * * Interoperation with old but supported protocol versions * should cause a warning to be printed. At a future date * the old protocol will become the minimum and * compatibility code removed. * * There are two possible explanations for the limit at * MAX_PROTOCOL_VERSION: either to allow new major-rev versions that * do not interoperate with us, and (more likely) so that we can * detect an attempt to connect rsync to a non-rsync server, which is * unlikely to begin by sending a byte between MIN_PROTOCL_VERSION and * MAX_PROTOCOL_VERSION. */ #define MIN_PROTOCOL_VERSION 20#define OLD_PROTOCOL_VERSION 25#define MAX_PROTOCOL_VERSION 40 #define MIN_FILECNT_LOOKAHEAD 1000#define MAX_FILECNT_LOOKAHEAD 10000 #define RSYNC_PORT 873 #define SPARSE_WRITE_SIZE (1024)#define WRITE_SIZE (32*1024)#define CHUNK_SIZE (32*1024)#define MAX_MAP_SIZE (256*1024)#define IO_BUFFER_SIZE (32*1024)#define MAX_BLOCK_SIZE ((int32)1 << 17) /* For compatibility with older rsyncs */#define OLD_MAX_BLOCK_SIZE ((int32)1 << 29) /* Policy ceilings on attacker-controlled wire values. Picked well above any * legitimate filesystem / protocol traffic but well below sizes that could * cause integer overflow or DoS-grade allocations. See input_checking.txt. * * Note on MAX_WIRE_XATTR_DATALEN: xattr datum size is bounded only by the * wire-format maximum (signed int32 varint, ~2GB). macOS resource forks * are transferred as the com.apple.ResourceFork xattr and can legitimately * be many GB; --max-alloc (default 1GB, configurable) is the real * allocation cap. read_varint_size() still rejects negative values so a * hostile peer cannot wrap to ~SIZE_MAX. */#define MAX_WIRE_XATTR_COUNT 65536#define MAX_WIRE_XATTR_NAMELEN 4096#define MAX_WIRE_XATTR_DATALEN ((int32)0x7fffffff)#define MAX_WIRE_ACL_COUNT 65536#define MAX_WIRE_NSEC 999999999/* MAX_WIRE_DEL_STAT is the per-category cap for read_del_stats() in main.c, * which accumulates 5 wire-supplied counts into the int32 stats.deleted_files * accumulator. Capped at 2^28 so 5 * 2^28 = 1.34 GB stays under INT32_MAX * (2.15 GB) with margin -- a higher cap (e.g. 2^30) would let a hostile peer * supplying 3+ max-sized counts overflow the accumulator, which is signed-int * UB. 2^28 is still well above any plausible real transfer's deletion count. */#define MAX_WIRE_DEL_STAT ((int32)1 << 28) #define ROUND_UP_1024(siz) ((siz) & (1024-1) ? ((siz) | (1024-1)) + 1 : (siz)) #define IOERR_GENERAL (1<<0) /* For backward compatibility, this must == 1 */#define IOERR_VANISHED (1<<1)#define IOERR_DEL_LIMIT (1<<2) /* Mask of all currently defined IOERR_* bits. Used to sanitize values * received from a peer via MSG_IO_ERROR so a malicious peer cannot set * arbitrary (undefined) bits in the local io_error, which would then be * stored and re-forwarded upstream. (Undefined bits never reach the exit * code: cleanup.c maps only these defined bits onto RERR_* values.) */#define IOERR_VALID_MASK (IOERR_GENERAL | IOERR_VANISHED | IOERR_DEL_LIMIT) #define MAX_ARGS 1000#define MAX_BASIS_DIRS 20#define MAX_SERVER_ARGS (MAX_BASIS_DIRS*2 + 100) #define COMPARE_DEST 1#define COPY_DEST 2#define LINK_DEST 3 #define MPLEX_BASE 7 #define NO_FILTERS 0#define SERVER_FILTERS 1#define ALL_FILTERS 2 #define XFLG_FATAL_ERRORS (1<<0)#define XFLG_OLD_PREFIXES (1<<1)#define XFLG_ANCHORED2ABS (1<<2) /* leading slash indicates absolute */#define XFLG_ABS_IF_SLASH (1<<3) /* leading or interior slash is absolute */#define XFLG_DIR2WILD3 (1<<4) /* dir/ match gets trailing *** added */ #define ATTRS_REPORT (1<<0)#define ATTRS_SKIP_MTIME (1<<1)#define ATTRS_ACCURATE_TIME (1<<2)#define ATTRS_SKIP_ATIME (1<<3)#define ATTRS_SKIP_CRTIME (1<<5) #define MSG_FLUSH 2#define FULL_FLUSH 1#define NORMAL_FLUSH 0 #define PDIR_CREATE 1#define PDIR_DELETE 0 /* Note: 0x00 - 0x7F are used for basis_dir[] indexes! */#define FNAMECMP_BASIS_DIR_LOW 0x00 /* Must remain 0! */#define FNAMECMP_BASIS_DIR_HIGH 0x7F#define FNAMECMP_FNAME 0x80#define FNAMECMP_PARTIAL_DIR 0x81#define FNAMECMP_BACKUP 0x82#define FNAMECMP_FUZZY 0x83 /* For use by the itemize_changes code */#define ITEM_REPORT_ATIME (1<<0)#define ITEM_REPORT_CHANGE (1<<1)#define ITEM_REPORT_SIZE (1<<2) /* regular files only */#define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */#define ITEM_REPORT_TIME (1<<3)#define ITEM_REPORT_PERMS (1<<4)#define ITEM_REPORT_OWNER (1<<5)#define ITEM_REPORT_GROUP (1<<6)#define ITEM_REPORT_ACL (1<<7)#define ITEM_REPORT_XATTR (1<<8)#define ITEM_REPORT_CRTIME (1<<10)#define ITEM_BASIS_TYPE_FOLLOWS (1<<11)#define ITEM_XNAME_FOLLOWS (1<<12)#define ITEM_IS_NEW (1<<13)#define ITEM_LOCAL_CHANGE (1<<14)#define ITEM_TRANSFER (1<<15)/* These are outside the range of the transmitted flags. */#define ITEM_MISSING_DATA (1<<16) /* used by log_formatted() */#define ITEM_DELETED (1<<17) /* used by log_formatted() */#define ITEM_MATCHED (1<<18) /* used by itemize() */ #define SIGNIFICANT_ITEM_FLAGS (~(\ ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE)) #define CFN_KEEP_DOT_DIRS (1<<0)#define CFN_KEEP_TRAILING_SLASH (1<<1)#define CFN_DROP_TRAILING_DOT_DIR (1<<2)#define CFN_COLLAPSE_DOT_DOT_DIRS (1<<3)#define CFN_REFUSE_DOT_DOT_DIRS (1<<4) #define SP_DEFAULT 0#define SP_KEEP_DOT_DIRS (1<<0) #define CD_NORMAL 0#define CD_SKIP_CHDIR 1 /* Log-message categories. FLOG only goes to the log file, not the client; * FCLIENT is the opposite. */enum logcode { FNONE=0, /* never sent */ FERROR_XFER=1, FINFO=2, /* sent over socket for any protocol */ FERROR=3, FWARNING=4, /* sent over socket for protocols >= 30 */ FERROR_SOCKET=5, FLOG=6, /* only sent via receiver -> generator pipe */ FERROR_UTF8=8, /* only sent via receiver -> generator pipe */ FCLIENT=7 /* never transmitted (e.g. server converts to FINFO) */}; /* Messages types that are sent over the message channel. The logcode * values must all be present here with identical numbers. */enum msgcode { MSG_DATA=0, /* raw data on the multiplexed stream */ MSG_ERROR_XFER=FERROR_XFER, MSG_INFO=FINFO, /* remote logging */ MSG_ERROR=FERROR, MSG_WARNING=FWARNING, /* protocol-30 remote logging */ MSG_ERROR_SOCKET=FERROR_SOCKET, /* sibling logging */ MSG_ERROR_UTF8=FERROR_UTF8, /* sibling logging */ MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, /* sibling logging */ MSG_REDO=9, /* reprocess indicated flist index */ MSG_STATS=10, /* message has stats data for generator */ MSG_IO_ERROR=22,/* the sending side had an I/O error */ MSG_IO_TIMEOUT=33,/* tell client about a daemon's timeout value */ MSG_NOOP=42, /* a do-nothing message (legacy protocol-30 only) */ MSG_ERROR_EXIT=86, /* synchronize an error exit (siblings and protocol >= 31) */ MSG_SUCCESS=100,/* successfully updated indicated flist index */ MSG_DELETED=101,/* successfully deleted a file on receiving side */ MSG_NO_SEND=102,/* sender failed to open a file we wanted */}; enum filetype { FT_UNSUPPORTED, FT_REG, FT_DIR, FT_SYMLINK, FT_SPECIAL, FT_DEVICE}; #define NDX_DONE -1#define NDX_FLIST_EOF -2#define NDX_DEL_STATS -3#define NDX_FLIST_OFFSET -101 /* For calling delete_item() and delete_dir_contents(). */#define DEL_NO_UID_WRITE (1<<0) /* file/dir has our uid w/o write perm */#define DEL_RECURSE (1<<1) /* if dir, delete all contents */#define DEL_DIR_IS_EMPTY (1<<2) /* internal delete_FUNCTIONS use only */#define DEL_FOR_FILE (1<<3) /* making room for a replacement file */#define DEL_FOR_DIR (1<<4) /* making room for a replacement dir */#define DEL_FOR_SYMLINK (1<<5) /* making room for a replacement symlink */#define DEL_FOR_DEVICE (1<<6) /* making room for a replacement device */#define DEL_FOR_SPECIAL (1<<7) /* making room for a replacement special */#define DEL_FOR_BACKUP (1<<8) /* the delete is for a backup operation */ #define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL) enum delret { DR_SUCCESS = 0, DR_FAILURE, DR_AT_LIMIT, DR_NOT_EMPTY}; /* Defines for make_path() */#define MKP_DROP_NAME (1<<0) /* drop trailing filename or trailing slash */#define MKP_SKIP_SLASH (1<<1) /* skip one or more leading slashes */ /* Defines for maybe_send_keepalive() */#define MSK_ALLOW_FLUSH (1<<0)#define MSK_ACTIVE_RECEIVER (1<<1) #include "errcode.h" #include "config.h" /* The default RSYNC_RSH is always set in config.h. */ #include <stdio.h>#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#ifdef STDC_HEADERS# include <stdlib.h># include <stddef.h>#else# ifdef HAVE_STDLIB_H# include <stdlib.h># endif#endif#ifdef HAVE_STRING_H# if !defined STDC_HEADERS && defined HAVE_MEMORY_H# include <memory.h># endif# include <string.h>#endif#ifdef HAVE_BSD_STRING_H# include <bsd/string.h>#endif#ifdef HAVE_STRINGS_H# include <strings.h>#endif#ifdef HAVE_INTTYPES_H# include <inttypes.h>#endif#ifdef HAVE_STDINT_H# include <stdint.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif #ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif #if defined HAVE_MALLOC_H && (defined HAVE_MALLINFO || !defined HAVE_STDLIB_H)#include <malloc.h>#endif #ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif #ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#include <time.h> #ifdef HAVE_FCNTL_H#include <fcntl.h>#else#ifdef HAVE_SYS_FCNTL_H#include <sys/fcntl.h>#endif#endif #ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h>#endif #ifdef HAVE_SYS_FILIO_H#include <sys/filio.h>#endif #include <signal.h>#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#ifdef HAVE_CTYPE_H#include <ctype.h>#endif#ifdef HAVE_GRP_H#include <grp.h>#endif#include <errno.h> /* O_NOFOLLOW refuses a final-component symlink with ELOOP on Linux, EMLINK on * FreeBSD, and EFTYPE on NetBSD/OpenBSD. Treat all three as "hit a symlink". A * genuine EMLINK (too many hard links) is harmless where this is used: callers * fall through to a readlink/lstat, which restores the real error. */#ifdef EFTYPE# define NOFOLLOW_HIT_SYMLINK(e) ((e) == ELOOP || (e) == EMLINK || (e) == EFTYPE)#else# define NOFOLLOW_HIT_SYMLINK(e) ((e) == ELOOP || (e) == EMLINK)#endif #ifdef HAVE_UTIME_H#include <utime.h>#endif #if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES || defined HAVE_SETATTRLIST#define CAN_SET_SYMLINK_TIMES 1#endif #if defined HAVE_LCHOWN || defined CHOWN_MODIFIES_SYMLINK#define CAN_CHOWN_SYMLINK 1#endif #if defined HAVE_LCHMOD || defined HAVE_SETATTRLIST#define CAN_CHMOD_SYMLINK 1#endif #if defined HAVE_UTIMENSAT || defined HAVE_SETATTRLIST#define CAN_SET_NSEC 1#endif #ifdef CAN_SET_NSEC#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC#define ST_MTIME_NSEC st_mtim.tv_nsec#define ST_ATIME_NSEC st_atim.tv_nsec#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)#define ST_MTIME_NSEC st_mtimensec#define ST_ATIME_NSEC st_atimensec#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)#define ST_MTIME_NSEC st_mtimespec.tv_nsec#define ST_ATIME_NSEC st_atimespec.tv_nsec#endif#endif #ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif #ifdef HAVE_SYS_MODE_H/* apparently AIX needs this for S_ISLNK */#ifndef S_ISLNK#include <sys/mode.h>#endif#endif /* these are needed for the uid/gid mapping code */#include <pwd.h>#include <grp.h> #include <stdarg.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef HAVE_NETDB_H#include <netdb.h>#endif#include <syslog.h>#ifdef HAVE_SYS_FILE_H#include <sys/file.h>#endifLines 1–500 of 1546. Load more
/* * Copyright (C) 1996, 2000 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> * Copyright (C) 2003-2022 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, visit the http://fsf.org website. */ #define False 0 #define True 1 #define Unset (-1) /* Our BOOL values are always an int. */ #define BLOCK_SIZE 700 #define RSYNC_RSH_ENV "RSYNC_RSH" #define RSYNC_RSH_IO_ENV "RSYNC_RSH_IO" #define RSYNC_NAME "rsync" /* RSYNCD_SYSCONF is now set in config.h */ #define RSYNCD_USERCONF "rsyncd.conf" #define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock" #define URL_PREFIX "rsync://" #define SYMLINK_PREFIX "/rsyncd-munged/" /* This MUST have a trailing slash! */ #define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1) #define BACKUP_SUFFIX "~" /* a non-zero CHAR_OFFSET makes the rolling sum stronger, but is incompatible with older versions :-( */ #define CHAR_OFFSET 0 /* These flags are only used during the flist transfer. */ #define XMIT_TOP_DIR (1<<0) #define XMIT_SAME_MODE (1<<1) #define XMIT_SAME_RDEV_pre28 (1<<2) /* protocols 20 - 27 */ #define XMIT_EXTENDED_FLAGS (1<<2) /* protocols 28 - now */ #define XMIT_SAME_UID (1<<3) #define XMIT_SAME_GID (1<<4) #define XMIT_SAME_NAME (1<<5) #define XMIT_LONG_NAME (1<<6) #define XMIT_SAME_TIME (1<<7) #define XMIT_SAME_RDEV_MAJOR (1<<8) /* protocols 28 - now (devices only) */ #define XMIT_NO_CONTENT_DIR (1<<8) /* protocols 30 - now (dirs only) */ #define XMIT_HLINKED (1<<9) /* protocols 28 - now (non-dirs) */ #define XMIT_SAME_DEV_pre30 (1<<10) /* protocols 28 - 29 */ #define XMIT_USER_NAME_FOLLOWS (1<<10) /* protocols 30 - now */ #define XMIT_RDEV_MINOR_8_pre30 (1<<11) /* protocols 28 - 29 */ #define XMIT_GROUP_NAME_FOLLOWS (1<<11) /* protocols 30 - now */ #define XMIT_HLINK_FIRST (1<<12) /* protocols 30 - now (HLINKED files only) */ #define XMIT_IO_ERROR_ENDLIST (1<<12) /* protocols 31*- now (w/XMIT_EXTENDED_FLAGS) (also protocol 30 w/'f' compat flag) */ #define XMIT_MOD_NSEC (1<<13) /* protocols 31 - now */ #define XMIT_SAME_ATIME (1<<14) /* any protocol - restricted by command-line option */ #define XMIT_UNUSED_15 (1<<15) /* unused flag bit */ /* The following XMIT flags require an rsync that uses a varint for the flag values */ #define XMIT_RESERVED_16 (1<<16) /* reserved for future fileflags use */ #define XMIT_CRTIME_EQ_MTIME (1<<17) /* any protocol - restricted by command-line option */ /* These flags are used in the live flist data. */ #define FLAG_TOP_DIR (1<<0) /* sender/receiver/generator */ #define FLAG_OWNED_BY_US (1<<0) /* generator: set by make_file() for aux flists only */ #define FLAG_FILE_SENT (1<<1) /* sender/receiver/generator */ #define FLAG_DIR_CREATED (1<<1) /* generator */ #define FLAG_CONTENT_DIR (1<<2) /* sender/receiver/generator */ #define FLAG_MOUNT_DIR (1<<3) /* sender/generator (dirs only) */ #define FLAG_SKIP_HLINK (1<<3) /* receiver/generator (w/FLAG_HLINKED) */ #define FLAG_DUPLICATE (1<<4) /* sender */ #define FLAG_MISSING_DIR (1<<4) /* generator */ #define FLAG_HLINKED (1<<5) /* receiver/generator (checked on all types) */ #define FLAG_HLINK_FIRST (1<<6) /* receiver/generator (w/FLAG_HLINKED) */ #define FLAG_IMPLIED_DIR (1<<6) /* sender/receiver/generator (dirs only) */ #define FLAG_HLINK_LAST (1<<7) /* receiver/generator */ #define FLAG_HLINK_DONE (1<<8) /* receiver/generator (checked on all types) */ #define FLAG_LENGTH64 (1<<9) /* sender/receiver/generator */ #define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */ #define FLAG_TIME_FAILED (1<<11)/* generator */ #define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */ #define FLAG_GOT_DIR_FLIST (1<<13)/* sender/receiver/generator - dir_flist only */ /* These flags are passed to functions but not stored. */ #define FLAG_DIVERT_DIRS (1<<16) /* sender, but must be unique */ #define FLAG_PERHAPS_DIR (1<<17) /* generator */ /* These flags are for get_dirlist(). */ #define GDL_IGNORE_FILTER_RULES (1<<0) #define GDL_PERHAPS_DIR (1<<1) /* Some helper macros for matching bits. */ #define BITS_SET(val,bits) (((val) & (bits)) == (bits)) #define BITS_SETnUNSET(val,onbits,offbits) (((val) & ((onbits)|(offbits))) == (onbits)) #define BITS_EQUAL(b1,b2,mask) (((unsigned)(b1) & (unsigned)(mask)) \ == ((unsigned)(b2) & (unsigned)(mask))) /* Update this if you make incompatible changes and ALSO update the * SUBPROTOCOL_VERSION if it is not a final (official) release. */ #define PROTOCOL_VERSION 32 /* This is used when working on a new protocol version or for any unofficial * protocol tweaks. It should be a non-zero value for each pre-release repo * change that affects the protocol. The official pre-release versions should * start with 1 (after incrementing the PROTOCOL_VERSION) and go up by 1 for * each new protocol change. For unofficial changes, pick a fairly large * random number that will hopefully not collide with anyone else's unofficial * protocol. It must ALWAYS be 0 when the protocol goes final (and official) * and NEVER before! When rsync negotiates a protocol match, it will only * allow the newest protocol to be used if the SUBPROTOCOL_VERSION matches. * All older protocol versions MUST be compatible with the final, official * release of the protocol, so don't tweak the code to change the protocol * behavior for an older protocol version. */ #define SUBPROTOCOL_VERSION 0 /* We refuse to interoperate with versions that are not in this range. * Note that we assume we'll work with later versions: the onus is on * people writing them to make sure that they don't send us anything * we won't understand. * * Interoperation with old but supported protocol versions * should cause a warning to be printed. At a future date * the old protocol will become the minimum and * compatibility code removed. * * There are two possible explanations for the limit at * MAX_PROTOCOL_VERSION: either to allow new major-rev versions that * do not interoperate with us, and (more likely) so that we can * detect an attempt to connect rsync to a non-rsync server, which is * unlikely to begin by sending a byte between MIN_PROTOCL_VERSION and * MAX_PROTOCOL_VERSION. */ #define MIN_PROTOCOL_VERSION 20 #define OLD_PROTOCOL_VERSION 25 #define MAX_PROTOCOL_VERSION 40 #define MIN_FILECNT_LOOKAHEAD 1000 #define MAX_FILECNT_LOOKAHEAD 10000 #define RSYNC_PORT 873 #define SPARSE_WRITE_SIZE (1024) #define WRITE_SIZE (32*1024) #define CHUNK_SIZE (32*1024) #define MAX_MAP_SIZE (256*1024) #define IO_BUFFER_SIZE (32*1024) #define MAX_BLOCK_SIZE ((int32)1 << 17) /* For compatibility with older rsyncs */ #define OLD_MAX_BLOCK_SIZE ((int32)1 << 29) /* Policy ceilings on attacker-controlled wire values. Picked well above any * legitimate filesystem / protocol traffic but well below sizes that could * cause integer overflow or DoS-grade allocations. See input_checking.txt. * * Note on MAX_WIRE_XATTR_DATALEN: xattr datum size is bounded only by the * wire-format maximum (signed int32 varint, ~2GB). macOS resource forks * are transferred as the com.apple.ResourceFork xattr and can legitimately * be many GB; --max-alloc (default 1GB, configurable) is the real * allocation cap. read_varint_size() still rejects negative values so a * hostile peer cannot wrap to ~SIZE_MAX. */ #define MAX_WIRE_XATTR_COUNT 65536 #define MAX_WIRE_XATTR_NAMELEN 4096 #define MAX_WIRE_XATTR_DATALEN ((int32)0x7fffffff) #define MAX_WIRE_ACL_COUNT 65536 #define MAX_WIRE_NSEC 999999999 /* MAX_WIRE_DEL_STAT is the per-category cap for read_del_stats() in main.c, * which accumulates 5 wire-supplied counts into the int32 stats.deleted_files * accumulator. Capped at 2^28 so 5 * 2^28 = 1.34 GB stays under INT32_MAX * (2.15 GB) with margin -- a higher cap (e.g. 2^30) would let a hostile peer * supplying 3+ max-sized counts overflow the accumulator, which is signed-int * UB. 2^28 is still well above any plausible real transfer's deletion count. */ #define MAX_WIRE_DEL_STAT ((int32)1 << 28) #define ROUND_UP_1024(siz) ((siz) & (1024-1) ? ((siz) | (1024-1)) + 1 : (siz)) #define IOERR_GENERAL (1<<0) /* For backward compatibility, this must == 1 */ #define IOERR_VANISHED (1<<1) #define IOERR_DEL_LIMIT (1<<2) /* Mask of all currently defined IOERR_* bits. Used to sanitize values * received from a peer via MSG_IO_ERROR so a malicious peer cannot set * arbitrary (undefined) bits in the local io_error, which would then be * stored and re-forwarded upstream. (Undefined bits never reach the exit * code: cleanup.c maps only these defined bits onto RERR_* values.) */ #define IOERR_VALID_MASK (IOERR_GENERAL | IOERR_VANISHED | IOERR_DEL_LIMIT) #define MAX_ARGS 1000 #define MAX_BASIS_DIRS 20 #define MAX_SERVER_ARGS (MAX_BASIS_DIRS*2 + 100) #define COMPARE_DEST 1 #define COPY_DEST 2 #define LINK_DEST 3 #define MPLEX_BASE 7 #define NO_FILTERS 0 #define SERVER_FILTERS 1 #define ALL_FILTERS 2 #define XFLG_FATAL_ERRORS (1<<0) #define XFLG_OLD_PREFIXES (1<<1) #define XFLG_ANCHORED2ABS (1<<2) /* leading slash indicates absolute */ #define XFLG_ABS_IF_SLASH (1<<3) /* leading or interior slash is absolute */ #define XFLG_DIR2WILD3 (1<<4) /* dir/ match gets trailing *** added */ #define ATTRS_REPORT (1<<0) #define ATTRS_SKIP_MTIME (1<<1) #define ATTRS_ACCURATE_TIME (1<<2) #define ATTRS_SKIP_ATIME (1<<3) #define ATTRS_SKIP_CRTIME (1<<5) #define MSG_FLUSH 2 #define FULL_FLUSH 1 #define NORMAL_FLUSH 0 #define PDIR_CREATE 1 #define PDIR_DELETE 0 /* Note: 0x00 - 0x7F are used for basis_dir[] indexes! */ #define FNAMECMP_BASIS_DIR_LOW 0x00 /* Must remain 0! */ #define FNAMECMP_BASIS_DIR_HIGH 0x7F #define FNAMECMP_FNAME 0x80 #define FNAMECMP_PARTIAL_DIR 0x81 #define FNAMECMP_BACKUP 0x82 #define FNAMECMP_FUZZY 0x83 /* For use by the itemize_changes code */ #define ITEM_REPORT_ATIME (1<<0) #define ITEM_REPORT_CHANGE (1<<1) #define ITEM_REPORT_SIZE (1<<2) /* regular files only */ #define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */ #define ITEM_REPORT_TIME (1<<3) #define ITEM_REPORT_PERMS (1<<4) #define ITEM_REPORT_OWNER (1<<5) #define ITEM_REPORT_GROUP (1<<6) #define ITEM_REPORT_ACL (1<<7) #define ITEM_REPORT_XATTR (1<<8) #define ITEM_REPORT_CRTIME (1<<10) #define ITEM_BASIS_TYPE_FOLLOWS (1<<11) #define ITEM_XNAME_FOLLOWS (1<<12) #define ITEM_IS_NEW (1<<13) #define ITEM_LOCAL_CHANGE (1<<14) #define ITEM_TRANSFER (1<<15) /* These are outside the range of the transmitted flags. */ #define ITEM_MISSING_DATA (1<<16) /* used by log_formatted() */ #define ITEM_DELETED (1<<17) /* used by log_formatted() */ #define ITEM_MATCHED (1<<18) /* used by itemize() */ #define SIGNIFICANT_ITEM_FLAGS (~(\ ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE)) #define CFN_KEEP_DOT_DIRS (1<<0) #define CFN_KEEP_TRAILING_SLASH (1<<1) #define CFN_DROP_TRAILING_DOT_DIR (1<<2) #define CFN_COLLAPSE_DOT_DOT_DIRS (1<<3) #define CFN_REFUSE_DOT_DOT_DIRS (1<<4) #define SP_DEFAULT 0 #define SP_KEEP_DOT_DIRS (1<<0) #define CD_NORMAL 0 #define CD_SKIP_CHDIR 1 /* Log-message categories. FLOG only goes to the log file, not the client; * FCLIENT is the opposite. */ enum logcode { FNONE=0, /* never sent */ FERROR_XFER=1, FINFO=2, /* sent over socket for any protocol */ FERROR=3, FWARNING=4, /* sent over socket for protocols >= 30 */ FERROR_SOCKET=5, FLOG=6, /* only sent via receiver -> generator pipe */ FERROR_UTF8=8, /* only sent via receiver -> generator pipe */ FCLIENT=7 /* never transmitted (e.g. server converts to FINFO) */ }; /* Messages types that are sent over the message channel. The logcode * values must all be present here with identical numbers. */ enum msgcode { MSG_DATA=0, /* raw data on the multiplexed stream */ MSG_ERROR_XFER=FERROR_XFER, MSG_INFO=FINFO, /* remote logging */ MSG_ERROR=FERROR, MSG_WARNING=FWARNING, /* protocol-30 remote logging */ MSG_ERROR_SOCKET=FERROR_SOCKET, /* sibling logging */ MSG_ERROR_UTF8=FERROR_UTF8, /* sibling logging */ MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, /* sibling logging */ MSG_REDO=9, /* reprocess indicated flist index */ MSG_STATS=10, /* message has stats data for generator */ MSG_IO_ERROR=22,/* the sending side had an I/O error */ MSG_IO_TIMEOUT=33,/* tell client about a daemon's timeout value */ MSG_NOOP=42, /* a do-nothing message (legacy protocol-30 only) */ MSG_ERROR_EXIT=86, /* synchronize an error exit (siblings and protocol >= 31) */ MSG_SUCCESS=100,/* successfully updated indicated flist index */ MSG_DELETED=101,/* successfully deleted a file on receiving side */ MSG_NO_SEND=102,/* sender failed to open a file we wanted */ }; enum filetype { FT_UNSUPPORTED, FT_REG, FT_DIR, FT_SYMLINK, FT_SPECIAL, FT_DEVICE }; #define NDX_DONE -1 #define NDX_FLIST_EOF -2 #define NDX_DEL_STATS -3 #define NDX_FLIST_OFFSET -101 /* For calling delete_item() and delete_dir_contents(). */ #define DEL_NO_UID_WRITE (1<<0) /* file/dir has our uid w/o write perm */ #define DEL_RECURSE (1<<1) /* if dir, delete all contents */ #define DEL_DIR_IS_EMPTY (1<<2) /* internal delete_FUNCTIONS use only */ #define DEL_FOR_FILE (1<<3) /* making room for a replacement file */ #define DEL_FOR_DIR (1<<4) /* making room for a replacement dir */ #define DEL_FOR_SYMLINK (1<<5) /* making room for a replacement symlink */ #define DEL_FOR_DEVICE (1<<6) /* making room for a replacement device */ #define DEL_FOR_SPECIAL (1<<7) /* making room for a replacement special */ #define DEL_FOR_BACKUP (1<<8) /* the delete is for a backup operation */ #define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL) enum delret { DR_SUCCESS = 0, DR_FAILURE, DR_AT_LIMIT, DR_NOT_EMPTY }; /* Defines for make_path() */ #define MKP_DROP_NAME (1<<0) /* drop trailing filename or trailing slash */ #define MKP_SKIP_SLASH (1<<1) /* skip one or more leading slashes */ /* Defines for maybe_send_keepalive() */ #define MSK_ALLOW_FLUSH (1<<0) #define MSK_ACTIVE_RECEIVER (1<<1) #include "errcode.h" #include "config.h" /* The default RSYNC_RSH is always set in config.h. */ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef STDC_HEADERS # include <stdlib.h> # include <stddef.h> #else # ifdef HAVE_STDLIB_H # include <stdlib.h> # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include <memory.h> # endif # include <string.h> #endif #ifdef HAVE_BSD_STRING_H # include <bsd/string.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif #ifdef HAVE_STDINT_H # include <stdint.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif #if defined HAVE_MALLOC_H && (defined HAVE_MALLINFO || !defined HAVE_STDLIB_H) #include <malloc.h> #endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif #include <time.h> #ifdef HAVE_FCNTL_H #include <fcntl.h> #else #ifdef HAVE_SYS_FCNTL_H #include <sys/fcntl.h> #endif #endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif #ifdef HAVE_SYS_FILIO_H #include <sys/filio.h> #endif #include <signal.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_CTYPE_H #include <ctype.h> #endif #ifdef HAVE_GRP_H #include <grp.h> #endif #include <errno.h> /* O_NOFOLLOW refuses a final-component symlink with ELOOP on Linux, EMLINK on * FreeBSD, and EFTYPE on NetBSD/OpenBSD. Treat all three as "hit a symlink". A * genuine EMLINK (too many hard links) is harmless where this is used: callers * fall through to a readlink/lstat, which restores the real error. */ #ifdef EFTYPE # define NOFOLLOW_HIT_SYMLINK(e) ((e) == ELOOP || (e) == EMLINK || (e) == EFTYPE) #else # define NOFOLLOW_HIT_SYMLINK(e) ((e) == ELOOP || (e) == EMLINK) #endif #ifdef HAVE_UTIME_H #include <utime.h> #endif #if defined HAVE_UTIMENSAT || defined HAVE_LUTIMES || defined HAVE_SETATTRLIST #define CAN_SET_SYMLINK_TIMES 1 #endif #if defined HAVE_LCHOWN || defined CHOWN_MODIFIES_SYMLINK #define CAN_CHOWN_SYMLINK 1 #endif #if defined HAVE_LCHMOD || defined HAVE_SETATTRLIST #define CAN_CHMOD_SYMLINK 1 #endif #if defined HAVE_UTIMENSAT || defined HAVE_SETATTRLIST #define CAN_SET_NSEC 1 #endif #ifdef CAN_SET_NSEC #ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC #define ST_MTIME_NSEC st_mtim.tv_nsec #define ST_ATIME_NSEC st_atim.tv_nsec #elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) #define ST_MTIME_NSEC st_mtimensec #define ST_ATIME_NSEC st_atimensec #elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) #define ST_MTIME_NSEC st_mtimespec.tv_nsec #define ST_ATIME_NSEC st_atimespec.tv_nsec #endif #endif #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> #endif #ifdef HAVE_SYS_MODE_H /* apparently AIX needs this for S_ISLNK */ #ifndef S_ISLNK #include <sys/mode.h> #endif #endif /* these are needed for the uid/gid mapping code */ #include <pwd.h> #include <grp.h> #include <stdarg.h> #include <netinet/in.h> #include <arpa/inet.h> #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <syslog.h> #ifdef HAVE_SYS_FILE_H #include <sys/file.h> #endif