From 4c15e80040f6ac2fc79d599d1722cf209cc30536 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 12 Jan 2008 18:57:10 +0000 Subject: [PATCH] The patches for 3.0.0pre8. --- atimes.diff | 10 +- checksum-updating.diff | 4 +- checksum-xattr.diff | 2 +- copy-devices.diff | 2 +- detect-renamed-lax.diff | 2 +- detect-renamed.diff | 16 +- downdate.diff | 30 +-- drop-cache.diff | 4 +- flags.diff | 18 +- fsync.diff | 2 +- link-by-hash.diff | 6 +- log-checksum.diff | 2 +- nameconverter.diff | 397 +++++++++++++++++++++++++++++++++ omit-dir-changes.diff | 2 +- openssl-support.diff | 4 +- preallocate.diff | 10 +- slp.diff | 6 +- source-filter_dest-filter.diff | 2 +- usermap.diff | 6 +- xattrs.diff | 30 +-- 20 files changed, 476 insertions(+), 79 deletions(-) create mode 100644 nameconverter.diff diff --git a/atimes.diff b/atimes.diff index 1b01c7e..d897f8a 100644 --- a/atimes.diff +++ b/atimes.diff @@ -143,7 +143,7 @@ diff --git a/generator.c b/generator.c #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST if (S_ISLNK(file->mode)) { ; -@@ -923,6 +927,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, +@@ -921,6 +925,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, if (link_dest) { if (!hard_link_one(file, fname, cmpbuf, 1)) goto try_a_copy; @@ -152,7 +152,7 @@ diff --git a/generator.c b/generator.c if (preserve_hard_links && F_IS_HLINKED(file)) finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j); if (itemizing && (verbose > 1 || stdout_format_has_i > 1)) { -@@ -1113,6 +1119,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, +@@ -1111,6 +1117,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, static void list_file_entry(struct file_struct *f) { char permbuf[PERMSTRING_SIZE]; @@ -160,7 +160,7 @@ diff --git a/generator.c b/generator.c double len; if (!F_IS_ACTIVE(f)) { -@@ -1127,14 +1134,16 @@ static void list_file_entry(struct file_struct *f) +@@ -1125,14 +1132,16 @@ static void list_file_entry(struct file_struct *f) #ifdef SUPPORT_LINKS if (preserve_links && S_ISLNK(f->mode)) { @@ -179,7 +179,7 @@ diff --git a/generator.c b/generator.c f_name(f, NULL)); } } -@@ -1884,7 +1893,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx) +@@ -1882,7 +1891,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx) if (!(file->mode & S_IWUSR)) do_chmod(fname, file->mode); if (need_retouch_dir_times) @@ -563,7 +563,7 @@ diff --git a/util.c b/util.c t[0].tv_usec = 0; t[1].tv_sec = modtime; t[1].tv_usec = 0; -@@ -154,12 +158,12 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) +@@ -155,12 +159,12 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode) return utimes(fname, t); #elif defined HAVE_STRUCT_UTIMBUF struct utimbuf tbuf; diff --git a/checksum-updating.diff b/checksum-updating.diff index 08498f2..653d58a 100644 --- a/checksum-updating.diff +++ b/checksum-updating.diff @@ -20,7 +20,7 @@ diff --git a/clientserver.c b/clientserver.c extern int io_timeout; extern int no_detach; extern int write_batch; -@@ -704,6 +705,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) +@@ -708,6 +709,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) else if (am_root < 0) /* Treat --fake-super from client as --super. */ am_root = 2; @@ -539,7 +539,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo --- a/rsyncd.conf.yo +++ b/rsyncd.conf.yo -@@ -237,6 +237,20 @@ locking on this file to ensure that the max connections limit is not +@@ -241,6 +241,20 @@ locking on this file to ensure that the max connections limit is not exceeded for the modules sharing the lock file. The default is tt(/var/run/rsyncd.lock). diff --git a/checksum-xattr.diff b/checksum-xattr.diff index 7eb2b6a..94953bb 100644 --- a/checksum-xattr.diff +++ b/checksum-xattr.diff @@ -178,7 +178,7 @@ diff --git a/xattrs.c b/xattrs.c typedef struct { char *datum, *name; -@@ -841,6 +845,39 @@ int del_def_xattr_acl(const char *fname) +@@ -853,6 +857,39 @@ int del_def_xattr_acl(const char *fname) } #endif diff --git a/copy-devices.diff b/copy-devices.diff index be1a45f..7cb23b0 100644 --- a/copy-devices.diff +++ b/copy-devices.diff @@ -19,7 +19,7 @@ diff --git a/generator.c b/generator.c extern int preserve_specials; extern int preserve_hard_links; extern int preserve_perms; -@@ -1566,7 +1567,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1564,7 +1565,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } diff --git a/detect-renamed-lax.diff b/detect-renamed-lax.diff index 38f029c..b1007ae 100644 --- a/detect-renamed-lax.diff +++ b/detect-renamed-lax.diff @@ -34,7 +34,7 @@ diff --git a/generator.c b/generator.c diff = u_strcmp(fmid->basename, f->basename); if (diff == 0) { good_match = mid; -@@ -1864,6 +1866,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1862,6 +1864,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fnamecmp = partialptr; fnamecmp_type = FNAMECMP_PARTIAL_DIR; statret = 0; diff --git a/detect-renamed.diff b/detect-renamed.diff index 6a30631..90f3803 100644 --- a/detect-renamed.diff +++ b/detect-renamed.diff @@ -452,7 +452,7 @@ diff --git a/generator.c b/generator.c if (do_progress && !am_server) rprintf(FINFO, " \r"); -@@ -1139,6 +1290,7 @@ static void list_file_entry(struct file_struct *f) +@@ -1137,6 +1288,7 @@ static void list_file_entry(struct file_struct *f) } } @@ -460,7 +460,7 @@ diff --git a/generator.c b/generator.c static int phase = 0; static int dflt_perms; -@@ -1383,8 +1535,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1381,8 +1533,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } } else if (delete_during && f_out != -1 && !phase && dry_run < 2 @@ -475,7 +475,7 @@ diff --git a/generator.c b/generator.c goto cleanup; } -@@ -1662,8 +1818,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1660,8 +1816,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } #endif @@ -491,7 +491,7 @@ diff --git a/generator.c b/generator.c rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s", full_fname(fname)); goto cleanup; -@@ -2000,6 +2162,12 @@ void generate_files(int f_out, const char *local_name) +@@ -2004,6 +2166,12 @@ void generate_files(int f_out, const char *local_name) if (verbose > 2) rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid()); @@ -504,7 +504,7 @@ diff --git a/generator.c b/generator.c if (delete_before && !solo_file && cur_flist->used > 0) do_delete_pass(); if (delete_during == 2) { -@@ -2010,7 +2178,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2014,7 +2182,7 @@ void generate_files(int f_out, const char *local_name) } do_progress = 0; @@ -513,7 +513,7 @@ diff --git a/generator.c b/generator.c whole_file = 0; if (verbose >= 2) { rprintf(FINFO, "delta-transmission %s\n", -@@ -2048,7 +2216,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2052,7 +2220,7 @@ void generate_files(int f_out, const char *local_name) dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); } else dirdev = MAKEDEV(0, 0); @@ -522,7 +522,7 @@ diff --git a/generator.c b/generator.c } } } -@@ -2091,7 +2259,21 @@ void generate_files(int f_out, const char *local_name) +@@ -2095,7 +2263,21 @@ void generate_files(int f_out, const char *local_name) } while ((cur_flist = cur_flist->next) != NULL); if (delete_during) @@ -634,7 +634,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -1022,6 +1022,32 @@ int handle_partial_dir(const char *fname, int create) +@@ -1019,6 +1019,32 @@ int handle_partial_dir(const char *fname, int create) return 1; } diff --git a/downdate.diff b/downdate.diff index 652d460..6fe7bed 100644 --- a/downdate.diff +++ b/downdate.diff @@ -18,7 +18,7 @@ diff --git a/generator.c b/generator.c extern int ignore_existing; extern int ignore_non_existing; extern int inplace; -@@ -1603,6 +1604,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1601,6 +1602,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } @@ -33,21 +33,21 @@ diff --git a/generator.c b/generator.c fnamecmp_type = FNAMECMP_FNAME; @@ -1917,6 +1925,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) - ignore_existing = -ignore_existing; - ignore_non_existing = -ignore_non_existing; - update_only = -update_only; -+ downdate_only = -downdate_only; - always_checksum = -always_checksum; - size_only = -size_only; - append_mode = -append_mode; + ignore_existing = -ignore_existing; + ignore_non_existing = -ignore_non_existing; + update_only = -update_only; ++ downdate_only = -downdate_only; + always_checksum = -always_checksum; + size_only = -size_only; + append_mode = -append_mode; @@ -1942,6 +1951,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) - ignore_existing = -ignore_existing; - ignore_non_existing = -ignore_non_existing; - update_only = -update_only; -+ downdate_only = -downdate_only; - always_checksum = -always_checksum; - size_only = -size_only; - append_mode = -append_mode; + ignore_existing = -ignore_existing; + ignore_non_existing = -ignore_non_existing; + update_only = -update_only; ++ downdate_only = -downdate_only; + always_checksum = -always_checksum; + size_only = -size_only; + append_mode = -append_mode; diff --git a/options.c b/options.c --- a/options.c +++ b/options.c diff --git a/drop-cache.diff b/drop-cache.diff index a18bd98..8c282e0 100644 --- a/drop-cache.diff +++ b/drop-cache.diff @@ -104,8 +104,8 @@ diff --git a/configure.in b/configure.in - extattr_get_link sigaction sigprocmask setattrlist) + extattr_get_link sigaction sigprocmask setattrlist posix_fadvise64) - AC_CHECK_FUNCS(getpgrp tcgetpgrp) - if test $ac_cv_func_getpgrp = yes; then + dnl cygwin iconv.h defines iconv_open as libiconv_open + if test x"$ac_cv_func_iconv_open" != x"yes"; then diff --git a/fileio.c b/fileio.c --- a/fileio.c +++ b/fileio.c diff --git a/flags.diff b/flags.diff index 3e3320d..2673e91 100644 --- a/flags.diff +++ b/flags.diff @@ -48,7 +48,7 @@ diff --git a/configure.in b/configure.in + chflags strerror putenv iconv_open locale_charset nl_langinfo getxattr \ extattr_get_link sigaction sigprocmask setattrlist) - AC_CHECK_FUNCS(getpgrp tcgetpgrp) + dnl cygwin iconv.h defines iconv_open as libiconv_open diff --git a/flist.c b/flist.c --- a/flist.c +++ b/flist.c @@ -263,7 +263,7 @@ diff --git a/generator.c b/generator.c } } -@@ -1296,7 +1307,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1294,7 +1305,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, * full later (right before we handle its contents). */ if (statret == 0 && (S_ISDIR(sx.st.st_mode) @@ -272,7 +272,7 @@ diff --git a/generator.c b/generator.c goto cleanup; /* Any errors get reported later. */ if (do_mkdir(fname, file->mode & 0700) == 0) file->flags |= FLAG_DIR_CREATED; -@@ -1308,7 +1319,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1306,7 +1317,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, * we need to delete it. If it doesn't exist, then * (perhaps recursively) create it. */ if (statret == 0 && !S_ISDIR(sx.st.st_mode)) { @@ -281,7 +281,7 @@ diff --git a/generator.c b/generator.c goto skipping_dir_contents; statret = -1; } -@@ -1437,7 +1448,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1435,7 +1446,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } /* Not the right symlink (or not a symlink), so * delete it. */ @@ -290,7 +290,7 @@ diff --git a/generator.c b/generator.c goto cleanup; } else if (basis_dir[0] != NULL) { int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, -@@ -1516,7 +1527,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1514,7 +1525,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto return_with_success; goto cleanup; } @@ -299,7 +299,7 @@ diff --git a/generator.c b/generator.c goto cleanup; } else if (basis_dir[0] != NULL) { int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, -@@ -1607,7 +1618,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1605,7 +1616,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fnamecmp_type = FNAMECMP_FNAME; if (statret == 0 && !S_ISREG(sx.st.st_mode)) { @@ -477,7 +477,7 @@ diff --git a/rsync.c b/rsync.c if (verbose > 1 && flags & ATTRS_REPORT) { if (updated) rprintf(FCLIENT, "%s\n", fname); -@@ -528,6 +583,9 @@ void finish_transfer(const char *fname, const char *fnametmp, +@@ -530,6 +585,9 @@ int finish_transfer(const char *fname, const char *fnametmp, set_file_attrs(fnametmp, file, NULL, fnamecmp, ok_to_set_time ? 0 : ATTRS_SKIP_MTIME); @@ -487,14 +487,14 @@ diff --git a/rsync.c b/rsync.c /* move tmp file over real file */ if (verbose > 2) rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname); -@@ -542,6 +600,9 @@ void finish_transfer(const char *fname, const char *fnametmp, +@@ -547,6 +605,9 @@ int finish_transfer(const char *fname, const char *fnametmp, } if (ret == 0) { /* The file was moved into place (not copied), so it's done. */ +#ifdef SUPPORT_FLAGS + undo_make_mutable(fname, file->mode, F_FFLAGS(file)); +#endif - return; + return 1; } /* The file was copied, so tweak the perms of the copied file. If it diff --git a/rsync.h b/rsync.h diff --git a/fsync.diff b/fsync.diff index dc856d8..fb8f076 100644 --- a/fsync.diff +++ b/fsync.diff @@ -90,7 +90,7 @@ diff --git a/util.c b/util.c extern int modify_window; extern int relative_paths; extern int human_readable; -@@ -314,6 +315,13 @@ int copy_file(const char *source, const char *dest, int ofd, +@@ -315,6 +316,13 @@ int copy_file(const char *source, const char *dest, int ofd, full_fname(source)); } diff --git a/link-by-hash.diff b/link-by-hash.diff index 7dcea6b..423c9a2 100644 --- a/link-by-hash.diff +++ b/link-by-hash.diff @@ -540,11 +540,11 @@ diff --git a/rsync.c b/rsync.c extern struct file_list *cur_flist, *first_flist, *dir_flist; extern struct chmod_mode_struct *daemon_chmod_modes; #ifdef ICONV_OPTION -@@ -531,8 +532,15 @@ void finish_transfer(const char *fname, const char *fnametmp, +@@ -533,8 +534,15 @@ int finish_transfer(const char *fname, const char *fnametmp, /* move tmp file over real file */ if (verbose > 2) rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname); -- ret = robust_rename(fnametmp, fname, partialptr, +- ret = robust_rename(fnametmp, fname, temp_copy_name, - file->mode & INITACCESSPERMS); +#ifdef HAVE_LINK + if (link_by_hash_dir) @@ -552,7 +552,7 @@ diff --git a/rsync.c b/rsync.c + else +#endif + { -+ ret = robust_rename(fnametmp, fname, partialptr, ++ ret = robust_rename(fnametmp, fname, temp_copy_name, + file->mode & INITACCESSPERMS); + } if (ret < 0) { diff --git a/log-checksum.diff b/log-checksum.diff index c24f568..7dd5f48 100644 --- a/log-checksum.diff +++ b/log-checksum.diff @@ -167,7 +167,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo --- a/rsyncd.conf.yo +++ b/rsyncd.conf.yo -@@ -460,7 +460,8 @@ quote(itemization( +@@ -464,7 +464,8 @@ quote(itemization( it() %a the remote IP address it() %b the number of bytes actually transferred it() %B the permission bits of the file (e.g. rwxrwxrwt) diff --git a/nameconverter.diff b/nameconverter.diff new file mode 100644 index 0000000..2f428c8 --- /dev/null +++ b/nameconverter.diff @@ -0,0 +1,397 @@ +This patch adds a "name converter" daemon option that allows you +to specify a user-/group- name converter program that converts +between ID numbers and names. This only works in daemon mode, +and is useful for both chroot use (since the converter runs +outside the chroot) or to specify a converter that doesn't use +the normal passwd/group setup. + +The converter must use a null char ('\0') as the line terminator +for input/output on stdin/stdout. A sample converter written in +perl is supplied in the support dir: nameconvert. To use it, +specify this daemon option: + + name converter = /path/nameconvert + +If /path/ is omitted, the script will be found on the $PATH. + +To use this patch, run these commands for a successful build: + + patch -p1 = (int)sizeof buf) { ++ rprintf(FERROR, "namecvt_name() request was too large.\n"); ++ exit_cleanup(RERR_UNSUPPORTED); ++ } ++ while ((got = write(namecvt_fd_req, buf, len + 1)) != len + 1) { ++ if (got < 0 && errno == EINTR) ++ continue; ++ rprintf(FERROR, "Connection to name-converter failed.\n"); ++ exit_cleanup(RERR_SOCKETIO); ++ } ++ if (!(len = read_arg_from_pipe(namecvt_fd_ans, buf, sizeof buf))) ++ return 0; ++ return atoi(buf); ++} ++ ++const char *namecvt_id(const char *cmd, int id) ++{ ++ char buf[1024]; ++ int got, len = snprintf(buf, sizeof buf, "%s %d", cmd, id); ++ if (len >= (int)sizeof buf) { ++ rprintf(FERROR, "namecvt_id() request was too large.\n"); ++ exit_cleanup(RERR_UNSUPPORTED); ++ } ++ while ((got = write(namecvt_fd_req, buf, len + 1)) != len + 1) { ++ if (got < 0 && errno == EINTR) ++ continue; ++ rprintf(FERROR, "Connection to name-converter failed.\n"); ++ exit_cleanup(RERR_SOCKETIO); ++ } ++ if (!(len = read_arg_from_pipe(namecvt_fd_ans, buf, sizeof buf))) ++ return NULL; ++ return strdup(buf); ++} ++ + /* send a list of available modules to the client. Don't list those + with "list = False". */ + static void send_listing(int fd) +diff --git a/loadparm.c b/loadparm.c +--- a/loadparm.c ++++ b/loadparm.c +@@ -139,6 +139,7 @@ typedef struct + char *log_file; + char *log_format; + char *name; ++ char *name_converter; + char *outgoing_chmod; + char *path; + char *postxfer_exec; +@@ -188,6 +189,7 @@ static service sDefault = + /* log_file; */ NULL, + /* log_format; */ "%o %h [%a] %m (%u) %f %l", + /* name; */ NULL, ++ /* name_converter; */ NULL, + /* outgoing_chmod; */ NULL, + /* path; */ NULL, + /* postxfer_exec; */ NULL, +@@ -323,6 +325,7 @@ static struct parm_struct parm_table[] = + {"max verbosity", P_INTEGER,P_LOCAL, &sDefault.max_verbosity, NULL,0}, + {"munge symlinks", P_BOOL, P_LOCAL, &sDefault.munge_symlinks, NULL,0}, + {"name", P_STRING, P_LOCAL, &sDefault.name, NULL,0}, ++ {"name converter", P_STRING, P_LOCAL, &sDefault.name_converter, NULL,0}, + {"outgoing chmod", P_STRING, P_LOCAL, &sDefault.outgoing_chmod, NULL,0}, + {"path", P_PATH, P_LOCAL, &sDefault.path, NULL,0}, + #ifdef HAVE_PUTENV +@@ -411,6 +414,7 @@ FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod) + FN_LOCAL_STRING(lp_path, path) + FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec) + FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec) ++FN_LOCAL_STRING(lp_name_converter, name_converter) + FN_LOCAL_STRING(lp_refuse_options, refuse_options) + FN_LOCAL_STRING(lp_secrets_file, secrets_file) + FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility) +diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo +--- a/rsyncd.conf.yo ++++ b/rsyncd.conf.yo +@@ -144,7 +144,10 @@ args if rsync believes they would escape the chroot. + The default for "use chroot" is true, and is the safer choice (especially + if the module is not read-only). + +-In order to preserve usernames and groupnames, rsync needs to be able to ++In order to preserve usernames and groupnames, you can use the ++bf(name converter) option to specify a name-converting program that the ++rsync daemon will start prior to enabling chroot (see the option for more ++details). If that option is not specified, the daemon needs to be able to + use the standard library functions for looking up names and IDs (i.e. + code(getpwuid()), code(getgrgid()), code(getpwname()), and code(getgrnam())). This means a + process in the chroot namespace will need to have access to the resources +@@ -200,6 +203,27 @@ path elements that rsync believes will allow a symlink to escape the module's + hierarchy. There are tricky ways to work around this, though, so you had + better trust your users if you choose this combination of options. + ++dit(bf(name converter)) The "name converter" option lets you specify a ++program that will be run by the rsync daemon (prior to bf(use chroot), if ++that option is enabled) to convert user/group names into numbers or visa ++versa. There is a sample perl script in the support directory named ++"nameconvert" that you can use to enable the use of the normal passwd/group ++lookup calls in a chroot daemon (which does not require any extra files ++be placed in the chroot area). This use is configured as follows: ++ ++verb( name converter = /path/nameconvert) ++ ++You could alternately specify a program that responds to each request using ++a lookup table to find the names and numbers, this allows you to configure ++per-module name conversion. See the support/nameconvert script for the ++details of what requests can be sent to the program. ++ ++The program will have access to some of the environment variables that are ++described in the section on bf(pre-xfer exec): bf(RSYNC_MODULE_NAME), ++bf(RSYNC_MODULE_PATH), bf(RSYNC_HOST_ADDR), bf(RSYNC_HOST_NAME), and ++bf(RSYNC_USER_NAME). This is useful if you want to customize the ++conversion using a single program invocation. ++ + dit(bf(max connections)) The "max connections" option allows you to + specify the maximum number of simultaneous connections you will allow. + Any clients connecting when the maximum has been reached will receive a +diff --git a/support/nameconvert b/support/nameconvert +new file mode 100755 +--- /dev/null ++++ b/support/nameconvert +@@ -0,0 +1,42 @@ ++#!/usr/bin/perl -w ++# This implements a simple protocol to do {user,group}-{name,id} ++# conversions. All input and output consists of simple strings ++# with a terminating null char (or newline for debugging). If ++# the conversion fails, an empty string is returned. ++# ++# The requests can be: ++# ++# uid ID_NUM\0 -> NAME\0 ++# gid ID_NUM\0 -> NAME\0 ++# usr NAME\0 -> ID_NUM\0 ++# grp NAME\0 -> ID_NUM\0 ++# ++# An unknown ID_NUM or NAME results in an empty return value. ++# ++# This is used by an rsync daemon when configured with the ++# "name converter" setting. ++ ++use strict; ++ ++my $eol = grep(/^--debug$/, @ARGV) ? "\n" : "\0"; ++$/ = $eol; ++ ++$| = 1; ++ ++while () { ++ chomp; ++ my $ans; ++ if (/^uid (\d+)$/) { ++ $ans = getpwuid($1); ++ } elsif (/^gid (\d+)$/) { ++ $ans = getgrgid($1); ++ } elsif (/^usr (\S+)$/) { ++ $ans = getpwnam($1); ++ } elsif (/^grp (\S+)$/) { ++ $ans = getgrnam($1); ++ } else { ++ die "Invalid request: $_"; ++ } ++ $ans = '' unless defined $ans; ++ print $ans, $eol; ++} +diff --git a/t_stub.c b/t_stub.c +--- a/t_stub.c ++++ b/t_stub.c +@@ -29,6 +29,7 @@ int module_dirlen = 0; + mode_t orig_umask = 002; + char *partial_dir; + char *module_dir; ++pid_t namecvt_pid; + struct filter_list_struct server_filter_list; + + void rprintf(UNUSED(enum logcode code), const char *format, ...) +@@ -69,6 +70,11 @@ struct filter_list_struct server_filter_list; + return -1; + } + ++ int namecvt_name(UNUSED(const char *cmd), UNUSED(const char *name)) ++{ ++ return 0; ++} ++ + char *lp_name(UNUSED(int mod)) + { + return NULL; +diff --git a/uidlist.c b/uidlist.c +--- a/uidlist.c ++++ b/uidlist.c +@@ -32,6 +32,7 @@ extern int preserve_uid; + extern int preserve_gid; + extern int preserve_acls; + extern int numeric_ids; ++extern pid_t namecvt_pid; + + #ifdef HAVE_GETGROUPS + # ifndef GETGROUPS_T +@@ -69,8 +70,12 @@ static struct idlist *add_to_list(struct idlist **root, id_t id, const char *nam + /* turn a uid into a user name */ + static const char *uid_to_name(uid_t uid) + { +- struct passwd *pass = getpwuid(uid); +- if (pass) ++ struct passwd *pass; ++ ++ if (namecvt_pid) ++ return namecvt_id("uid", (int)uid); ++ ++ if ((pass = getpwuid(uid)) != NULL) + return strdup(pass->pw_name); + return NULL; + } +@@ -78,8 +83,12 @@ static const char *uid_to_name(uid_t uid) + /* turn a gid into a group name */ + static const char *gid_to_name(gid_t gid) + { +- struct group *grp = getgrgid(gid); +- if (grp) ++ struct group *grp; ++ ++ if (namecvt_pid) ++ return namecvt_id("gid", (int)gid); ++ ++ if ((grp = getgrgid(gid)) != NULL) + return strdup(grp->gr_name); + return NULL; + } +diff --git a/util.c b/util.c +--- a/util.c ++++ b/util.c +@@ -30,9 +30,10 @@ extern int modify_window; + extern int relative_paths; + extern int human_readable; + extern char *module_dir; +-extern unsigned int module_dirlen; + extern mode_t orig_umask; + extern char *partial_dir; ++extern pid_t namecvt_pid; ++extern unsigned int module_dirlen; + extern struct filter_list_struct server_filter_list; + + int sanitize_paths = 0; +@@ -468,24 +469,44 @@ void kill_all(int sig) + /** Turn a user name into a uid */ + int name_to_uid(const char *name, uid_t *uid_p) + { +- struct passwd *pass; ++ uid_t uid; ++ + if (!name || !*name) + return 0; +- if (!(pass = getpwnam(name))) +- return 0; +- *uid_p = pass->pw_uid; ++ ++ if (namecvt_pid) { ++ if (!(uid = namecvt_name("usr", name))) ++ return 0; ++ } else { ++ struct passwd *pass; ++ if (!(pass = getpwnam(name))) ++ return 0; ++ uid = pass->pw_uid; ++ } ++ ++ *uid_p = uid; + return 1; + } + + /** Turn a group name into a gid */ + int name_to_gid(const char *name, gid_t *gid_p) + { +- struct group *grp; ++ gid_t gid; ++ + if (!name || !*name) + return 0; +- if (!(grp = getgrnam(name))) +- return 0; +- *gid_p = grp->gr_gid; ++ ++ if (namecvt_pid) { ++ if (!(gid = namecvt_name("grp", name))) ++ return 0; ++ } else { ++ struct group *grp; ++ if (!(grp = getgrnam(name))) ++ return 0; ++ gid = grp->gr_gid; ++ } ++ ++ *gid_p = gid; + return 1; + } + diff --git a/omit-dir-changes.diff b/omit-dir-changes.diff index 58ad0c3..9be94e3 100644 --- a/omit-dir-changes.diff +++ b/omit-dir-changes.diff @@ -41,7 +41,7 @@ diff --git a/generator.c b/generator.c iflags |= ITEM_REPORT_GROUP; #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { -@@ -1321,7 +1324,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1319,7 +1322,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, real_sx = sx; if (file->flags & FLAG_DIR_CREATED) statret = -1; diff --git a/openssl-support.diff b/openssl-support.diff index e6b1e13..8dc8924 100644 --- a/openssl-support.diff +++ b/openssl-support.diff @@ -163,7 +163,7 @@ diff --git a/clientserver.c b/clientserver.c return -1; } -@@ -835,6 +882,9 @@ int start_daemon(int f_in, int f_out) +@@ -839,6 +886,9 @@ int start_daemon(int f_in, int f_out) if (exchange_protocols(f_in, f_out, line, sizeof line, 0) < 0) return -1; @@ -173,7 +173,7 @@ diff --git a/clientserver.c b/clientserver.c line[0] = 0; if (!read_line_old(f_in, line, sizeof line)) return -1; -@@ -846,6 +896,20 @@ int start_daemon(int f_in, int f_out) +@@ -850,6 +900,20 @@ int start_daemon(int f_in, int f_out) return -1; } diff --git a/preallocate.diff b/preallocate.diff index f59b856..f5f21a4 100644 --- a/preallocate.diff +++ b/preallocate.diff @@ -19,8 +19,8 @@ diff --git a/configure.in b/configure.in - extattr_get_link sigaction sigprocmask setattrlist) + extattr_get_link sigaction sigprocmask setattrlist posix_fallocate) - AC_CHECK_FUNCS(getpgrp tcgetpgrp) - if test $ac_cv_func_getpgrp = yes; then + dnl cygwin iconv.h defines iconv_open as libiconv_open + if test x"$ac_cv_func_iconv_open" != x"yes"; then diff --git a/options.c b/options.c --- a/options.c +++ b/options.c @@ -224,7 +224,7 @@ diff --git a/util.c b/util.c extern int module_id; extern int modify_window; extern int relative_paths; -@@ -272,6 +273,10 @@ int copy_file(const char *source, const char *dest, int ofd, +@@ -273,6 +274,10 @@ int copy_file(const char *source, const char *dest, int ofd, int ifd; char buf[1024 * 8]; int len; /* Number of bytes read into `buf'. */ @@ -235,7 +235,7 @@ diff --git a/util.c b/util.c if ((ifd = do_open(source, O_RDONLY, 0)) < 0) { rsyserr(FERROR_XFER, errno, "open %s", full_fname(source)); -@@ -293,7 +298,27 @@ int copy_file(const char *source, const char *dest, int ofd, +@@ -294,7 +299,27 @@ int copy_file(const char *source, const char *dest, int ofd, } } @@ -263,7 +263,7 @@ diff --git a/util.c b/util.c if (full_write(ofd, buf, len) < 0) { rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest)); close(ifd); -@@ -314,6 +339,16 @@ int copy_file(const char *source, const char *dest, int ofd, +@@ -315,6 +340,16 @@ int copy_file(const char *source, const char *dest, int ofd, full_fname(source)); } diff --git a/slp.diff b/slp.diff index 276830a..12dd4b6 100644 --- a/slp.diff +++ b/slp.diff @@ -43,7 +43,7 @@ diff --git a/Makefile.in b/Makefile.in diff --git a/clientserver.c b/clientserver.c --- a/clientserver.c +++ b/clientserver.c -@@ -969,6 +969,13 @@ int daemon_main(void) +@@ -973,6 +973,13 @@ int daemon_main(void) * address too. In fact, why not just do inet_ntop on the * local address??? */ @@ -60,7 +60,7 @@ diff --git a/clientserver.c b/clientserver.c diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in -@@ -632,6 +632,29 @@ if test $rsync_cv_can_hardlink_special = yes; then +@@ -637,6 +637,29 @@ if test $rsync_cv_can_hardlink_special = yes; then AC_DEFINE(CAN_HARDLINK_SPECIAL, 1, [Define to 1 if link() can hard-link special files.]) fi @@ -235,7 +235,7 @@ diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo enddit() -@@ -603,6 +612,7 @@ use chroot = no +@@ -607,6 +616,7 @@ use chroot = no max connections = 4 syslog facility = local5 pid file = /var/run/rsyncd.pid diff --git a/source-filter_dest-filter.diff b/source-filter_dest-filter.diff index a395b51..5a5bf15 100644 --- a/source-filter_dest-filter.diff +++ b/source-filter_dest-filter.diff @@ -309,8 +309,8 @@ diff --git a/receiver.c b/receiver.c + } + if ((recv_ok && (!delay_updates || !partialptr)) || inplace) { - char *temp_copy_name; if (partialptr == fname) + partialptr = NULL; diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h diff --git a/usermap.diff b/usermap.diff index 439a6e1..2b89567 100644 --- a/usermap.diff +++ b/usermap.diff @@ -188,7 +188,7 @@ diff --git a/uidlist.c b/uidlist.c + struct idlist { struct idlist *next; - char *name; + const char *name; @@ -48,8 +54,8 @@ struct idlist { uint16 flags; }; @@ -198,9 +198,9 @@ diff --git a/uidlist.c b/uidlist.c +static struct idlist *uidlist, *uidmap; +static struct idlist *gidlist, *gidmap; - static struct idlist *add_to_list(struct idlist **root, id_t id, char *name, + static struct idlist *add_to_list(struct idlist **root, id_t id, const char *name, id_t id2, uint16 flags) -@@ -84,22 +90,6 @@ static char *gid_to_name(gid_t gid) +@@ -84,22 +90,6 @@ static const char *gid_to_name(gid_t gid) return NULL; } diff --git a/xattrs.diff b/xattrs.diff index 72807f0..0768dae 100644 --- a/xattrs.diff +++ b/xattrs.diff @@ -46,7 +46,7 @@ diff --git a/xattrs.c b/xattrs.c #define RSYNC_XAL_INITIAL 5 #define RSYNC_XAL_LIST_INITIAL 100 -@@ -241,7 +243,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp) +@@ -242,7 +244,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp) if (!(ptr = get_xattr_data(fname, name, &datum_len, 0))) return -1; @@ -55,7 +55,7 @@ diff --git a/xattrs.c b/xattrs.c /* For large datums, we store a flag and a checksum. */ name_offset = 1 + MAX_DIGEST_LEN; sum_init(checksum_seed); -@@ -305,7 +307,7 @@ static int find_matching_xattr(item_list *xalp) +@@ -310,7 +312,7 @@ static int find_matching_xattr(item_list *xalp) || rxas1[j].datum_len != rxas2[j].datum_len || strcmp(rxas1[j].name, rxas2[j].name)) break; @@ -64,7 +64,7 @@ diff --git a/xattrs.c b/xattrs.c if (memcmp(rxas1[j].datum + 1, rxas2[j].datum + 1, MAX_DIGEST_LEN) != 0) -@@ -342,34 +344,43 @@ int send_xattr(stat_x *sxp, int f) +@@ -347,34 +349,43 @@ int send_xattr(stat_x *sxp, int f) { int ndx = find_matching_xattr(sxp->xattr); @@ -118,7 +118,7 @@ diff --git a/xattrs.c b/xattrs.c write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN); else write_buf(f, rxa->datum, rxa->datum_len); -@@ -419,7 +430,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) +@@ -424,7 +435,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1; if (cmp > 0) same = 0; @@ -127,19 +127,19 @@ diff --git a/xattrs.c b/xattrs.c same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1, MAX_DIGEST_LEN) == 0; -@@ -462,6 +473,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) - int j, cnt, prior_req = -1; +@@ -467,6 +478,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) + int cnt, prior_req = 0; rsync_xa *rxa; + if (protocol_version < 30) + return; + lst += F_XATTR(file); - cnt = lst->count; - for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) { -@@ -536,6 +550,9 @@ int recv_xattr_request(struct file_struct *file, int f_in) + for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) { + if (rxa->datum_len <= MAX_FULL_DATUM) +@@ -540,6 +554,9 @@ int recv_xattr_request(struct file_struct *file, int f_in) rsync_xa *rxa; - int rel_pos, cnt, got_xattr_data = 0; + int rel_pos, cnt, num, got_xattr_data = 0; + if (protocol_version < 30) + return 0; @@ -147,10 +147,10 @@ diff --git a/xattrs.c b/xattrs.c if (F_XATTR(file) < 0) { rprintf(FERROR, "recv_xattr_request: internal data error!\n"); exit_cleanup(RERR_STREAMIO); -@@ -585,7 +602,22 @@ void receive_xattr(struct file_struct *file, int f) +@@ -596,7 +613,22 @@ void receive_xattr(struct file_struct *file, int f) { static item_list temp_xattr = EMPTY_ITEM_LIST; - int count; + int count, num; - int ndx = read_varint(f); + int ndx; + @@ -171,7 +171,7 @@ diff --git a/xattrs.c b/xattrs.c if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) { rprintf(FERROR, "receive_xattr: xa index %d out of" -@@ -598,7 +630,7 @@ void receive_xattr(struct file_struct *file, int f) +@@ -609,7 +641,7 @@ void receive_xattr(struct file_struct *file, int f) return; } @@ -180,8 +180,8 @@ diff --git a/xattrs.c b/xattrs.c (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count); temp_xattr.count = 0; } -@@ -606,9 +638,10 @@ void receive_xattr(struct file_struct *file, int f) - while (count--) { +@@ -617,9 +649,10 @@ void receive_xattr(struct file_struct *file, int f) + for (num = 1; num <= count; num++) { char *ptr, *name; rsync_xa *rxa; - size_t name_len = read_varint(f); -- 2.34.1