+++ /dev/null
-A patch to add two new daemon module options:
-
- pre-xfer exec = COMMAND
- post-xfer exec = COMMAND
-
-The "pre-xfer exec" command runs before the transfer happens, while the
-'post-xfer exec" command runs after the transfer completes, even if the
-transfer failed. The following environment variables will be set in
-both cases:
-
- RSYNC_MODULE_NAME The name of the module being accessed.
- RSYNC_MODULE_PATH The path configured for the module.
- RSYNC_HOST_ADDR The accessing host's IP address.
- RSYNC_HOST_NAME The accessing host's name.
- RSYNC_USER_NAME The accessing user's name.
-
-These environment variables will also be set for the "post-xfer exec"
-command:
-
- RSYNC_EXIT_STATUS rsync's exit value. This will be 0 for a
- successful run, a positive value for an error
- that rsync returned (e.g. 23=partial xfer),
- or a -1 if rsync failed to exit properly.
- RSYNC_RAW_STATUS the raw exit value from waitpid().
-
-Both commands are run by the user that started the daemon (not the
-module's uid/gid setting) without any chroot() restrictions (even if
-the module will/has run chroot()ed).
-
-After applying this patch, run these commands for a successful build:
-
- autoconf
- autoheader
- ./configure
- make proto
- make
-
---- orig/clientserver.c 2005-06-10 21:33:27
-+++ clientserver.c 2005-07-28 10:27:33
-@@ -227,6 +227,9 @@ static int rsync_module(int f_in, int f_
- uid_t uid = (uid_t)-2; /* canonically "nobody" */
- gid_t gid = (gid_t)-2;
- char *p;
-+#ifdef HAVE_PUTENV
-+ char *s;
-+#endif
- char *addr = client_addr(f_in);
- char *host = client_name(f_in);
- char *name = lp_name(i);
-@@ -347,6 +350,58 @@ static int rsync_module(int f_in, int f_
-
- log_init();
-
-+#ifdef HAVE_PUTENV
-+ s = lp_prexfer_exec(i);
-+ p = lp_postxfer_exec(i);
-+ if ((s && *s) || (p && *p)) {
-+ char *modname, *modpath, *hostaddr, *hostname, *username;
-+ int status;
-+ if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
-+ || asprintf(&modpath, "RSYNC_MODULE_PATH=%s", lp_path(i)) < 0
-+ || asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
-+ || asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
-+ || asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
-+ out_of_memory("rsync_module");
-+ putenv(modname);
-+ putenv(modpath);
-+ putenv(hostaddr);
-+ putenv(hostname);
-+ putenv(username);
-+ umask(orig_umask);
-+ if (s && *s) {
-+ status = system(s);
-+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-+ rprintf(FLOG, "prexfer-exec failed\n");
-+ io_printf(f_out, "@ERROR: prexfer-exec failed\n");
-+ return -1;
-+ }
-+ }
-+ if (p && *p) {
-+ pid_t pid = fork();
-+ if (pid < 0) {
-+ rsyserr(FLOG, errno, "fork failed");
-+ io_printf(f_out, "@ERROR: fork failed\n");
-+ return -1;
-+ }
-+ if (pid) {
-+ char *ret1, *ret2;
-+ waitpid(pid, &status, 0);
-+ if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0)
-+ putenv(ret1);
-+ if (WIFEXITED(status))
-+ status = WEXITSTATUS(status);
-+ else
-+ status = -1;
-+ if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0)
-+ putenv(ret2);
-+ system(p);
-+ _exit(0);
-+ }
-+ }
-+ umask(0);
-+ }
-+#endif
-+
- if (use_chroot) {
- /*
- * XXX: The 'use chroot' flag is a fairly reliable
---- orig/configure.in 2005-07-27 23:31:12
-+++ configure.in 2005-07-28 10:27:34
-@@ -501,7 +501,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strd
- memmove lchown vsnprintf snprintf vasprintf asprintf setsid glob strpbrk \
- strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
- setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
-- strerror)
-+ strerror putenv)
-
- AC_CHECK_FUNCS(getpgrp tcgetpgrp)
- if test $ac_cv_func_getpgrp = yes; then
---- orig/loadparm.c 2005-06-10 21:33:28
-+++ loadparm.c 2005-07-28 10:27:34
-@@ -140,6 +140,8 @@ typedef struct
- char *log_format;
- char *refuse_options;
- char *dont_compress;
-+ char *prexfer_exec;
-+ char *postxfer_exec;
- int timeout;
- int max_connections;
- int max_verbosity;
-@@ -175,6 +177,8 @@ static service sDefault =
- "%o %h [%a] %m (%u) %f %l", /* log format */
- NULL, /* refuse options */
- "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
-+ NULL, /* prexfer_exec */
-+ NULL, /* postxfer_exec */
- 0, /* timeout */
- 0, /* max connections */
- 1, /* max verbosity */
-@@ -298,6 +302,10 @@ static struct parm_struct parm_table[] =
- {"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
- {"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
- {"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
-+#ifdef HAVE_PUTENV
-+ {"pre-xfer exec", P_STRING, P_LOCAL, &sDefault.prexfer_exec, NULL, 0},
-+ {"post-xfer exec", P_STRING, P_LOCAL, &sDefault.postxfer_exec,NULL, 0},
-+#endif
- {NULL, P_BOOL, P_NONE, NULL, NULL, 0}
- };
-
-@@ -379,6 +387,8 @@ FN_LOCAL_STRING(lp_include_from, include
- FN_LOCAL_STRING(lp_log_format, log_format)
- FN_LOCAL_STRING(lp_refuse_options, refuse_options)
- FN_LOCAL_STRING(lp_dont_compress, dont_compress)
-+FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
-+FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
- FN_LOCAL_INTEGER(lp_timeout, timeout)
- FN_LOCAL_INTEGER(lp_max_connections, max_connections)
- FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
---- orig/rsyncd.conf.yo 2005-07-28 09:59:28
-+++ rsyncd.conf.yo 2005-07-28 10:27:35
-@@ -454,6 +454,35 @@ of the patterns will not be compressed d
-
- The default setting is tt(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
-
-+dit(bf(pre-xfer exec), bf(post-xfer exec)) You may specify a command to be run
-+before and/or after the transfer. If the bf(pre-xfer exec) command fails, the
-+transfer is aborted before it begins.
-+
-+The following environment variables are set for both commands:
-+
-+quote(itemize(
-+ it() bf(RSYNC_MODULE_NAME): The name of the module being accessed.
-+ it() bf(RSYNC_MODULE_PATH): The path configured for the module.
-+ it() bf(RSYNC_HOST_ADDR): The accessing host's IP address.
-+ it() bf(RSYNC_HOST_NAME): The accessing host's name.
-+ it() bf(RSYNC_USER_NAME): The accessing user's name (empty if no user).
-+))
-+
-+These environment variables will also be set for the bf(post-xfer exec)
-+command:
-+
-+quote(itemize(
-+ it() bf(RSYNC_EXIT_STATUS): rsync's exit value. This will be 0 for a
-+ successful run, a positive value for an error that rsync returned
-+ (e.g. 23=partial xfer), or a -1 if rsync failed to exit properly.
-+ it() bf(RSYNC_RAW_STATUS): the raw exit value from waitpid().
-+))
-+
-+Even though the commands can be associated with a particular module, they
-+are run using the permissions of the user that started the daemon (not the
-+module's uid/gid setting) without any chroot restrictions (even if the
-+module will/has run chroot()ed).
-+
- enddit()
-
- manpagesection(AUTHENTICATION STRENGTH)