1 A patch to add two new daemon module options:
3 pre-xfer exec = COMMAND
4 post-xfer exec = COMMAND
6 The "pre-xfer exec" command runs before the transfer happens, while the
7 'post-xfer exec" command runs after the transfer completes, even if the
8 transfer failed. The following environment variables will be set in
11 RSYNC_MODULE_NAME The name of the module being accessed.
12 RSYNC_MODULE_PATH The path configured for the module.
13 RSYNC_HOST_ADDR The accessing host's IP address.
14 RSYNC_HOST_NAME The accessing host's name.
15 RSYNC_USER_NAME The accessing user's name.
17 These environment variables will also be set for the "post-xfer exec"
20 RSYNC_EXIT_STATUS rsync's exit value. This will be 0 for a
21 successful run, a positive value for an error
22 that rsync returned (e.g. 23=partial xfer),
23 or a -1 if rsync failed to exit properly.
24 RSYNC_RAW_STATUS the raw exit value from waitpid().
26 Both commands are run by the user that started the daemon (not the
27 module's uid/gid setting) without any chroot() restrictions (even if
28 the module will/has run chroot()ed).
30 After applying this patch, run these commands for a successful build:
38 --- orig/clientserver.c 2005-06-10 21:33:27
39 +++ clientserver.c 2005-07-28 10:27:33
40 @@ -227,6 +227,9 @@ static int rsync_module(int f_in, int f_
41 uid_t uid = (uid_t)-2; /* canonically "nobody" */
42 gid_t gid = (gid_t)-2;
47 char *addr = client_addr(f_in);
48 char *host = client_name(f_in);
49 char *name = lp_name(i);
50 @@ -347,6 +350,58 @@ static int rsync_module(int f_in, int f_
55 + s = lp_prexfer_exec(i);
56 + p = lp_postxfer_exec(i);
57 + if ((s && *s) || (p && *p)) {
58 + char *modname, *modpath, *hostaddr, *hostname, *username;
60 + if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
61 + || asprintf(&modpath, "RSYNC_MODULE_PATH=%s", lp_path(i)) < 0
62 + || asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
63 + || asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
64 + || asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
65 + out_of_memory("rsync_module");
74 + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
75 + rprintf(FLOG, "prexfer-exec failed\n");
76 + io_printf(f_out, "@ERROR: prexfer-exec failed\n");
83 + rsyserr(FLOG, errno, "fork failed");
84 + io_printf(f_out, "@ERROR: fork failed\n");
89 + waitpid(pid, &status, 0);
90 + if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0)
92 + if (WIFEXITED(status))
93 + status = WEXITSTATUS(status);
96 + if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0)
108 * XXX: The 'use chroot' flag is a fairly reliable
109 --- orig/configure.in 2005-07-27 23:31:12
110 +++ configure.in 2005-07-28 10:27:34
111 @@ -501,7 +501,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strd
112 memmove lchown vsnprintf snprintf vasprintf asprintf setsid glob strpbrk \
113 strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
114 setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
118 AC_CHECK_FUNCS(getpgrp tcgetpgrp)
119 if test $ac_cv_func_getpgrp = yes; then
120 --- orig/loadparm.c 2005-06-10 21:33:28
121 +++ loadparm.c 2005-07-28 10:27:34
122 @@ -140,6 +140,8 @@ typedef struct
124 char *refuse_options;
126 + char *prexfer_exec;
127 + char *postxfer_exec;
131 @@ -175,6 +177,8 @@ static service sDefault =
132 "%o %h [%a] %m (%u) %f %l", /* log format */
133 NULL, /* refuse options */
134 "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
135 + NULL, /* prexfer_exec */
136 + NULL, /* postxfer_exec */
138 0, /* max connections */
139 1, /* max verbosity */
140 @@ -298,6 +302,10 @@ static struct parm_struct parm_table[] =
141 {"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
142 {"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
143 {"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
145 + {"pre-xfer exec", P_STRING, P_LOCAL, &sDefault.prexfer_exec, NULL, 0},
146 + {"post-xfer exec", P_STRING, P_LOCAL, &sDefault.postxfer_exec,NULL, 0},
148 {NULL, P_BOOL, P_NONE, NULL, NULL, 0}
151 @@ -379,6 +387,8 @@ FN_LOCAL_STRING(lp_include_from, include
152 FN_LOCAL_STRING(lp_log_format, log_format)
153 FN_LOCAL_STRING(lp_refuse_options, refuse_options)
154 FN_LOCAL_STRING(lp_dont_compress, dont_compress)
155 +FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
156 +FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
157 FN_LOCAL_INTEGER(lp_timeout, timeout)
158 FN_LOCAL_INTEGER(lp_max_connections, max_connections)
159 FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
160 --- orig/rsyncd.conf.yo 2005-07-28 09:59:28
161 +++ rsyncd.conf.yo 2005-07-28 10:27:35
162 @@ -454,6 +454,35 @@ of the patterns will not be compressed d
164 The default setting is tt(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
166 +dit(bf(pre-xfer exec), bf(post-xfer exec)) You may specify a command to be run
167 +before and/or after the transfer. If the bf(pre-xfer exec) command fails, the
168 +transfer is aborted before it begins.
170 +The following environment variables are set for both commands:
173 + it() bf(RSYNC_MODULE_NAME): The name of the module being accessed.
174 + it() bf(RSYNC_MODULE_PATH): The path configured for the module.
175 + it() bf(RSYNC_HOST_ADDR): The accessing host's IP address.
176 + it() bf(RSYNC_HOST_NAME): The accessing host's name.
177 + it() bf(RSYNC_USER_NAME): The accessing user's name (empty if no user).
180 +These environment variables will also be set for the bf(post-xfer exec)
184 + it() bf(RSYNC_EXIT_STATUS): rsync's exit value. This will be 0 for a
185 + successful run, a positive value for an error that rsync returned
186 + (e.g. 23=partial xfer), or a -1 if rsync failed to exit properly.
187 + it() bf(RSYNC_RAW_STATUS): the raw exit value from waitpid().
190 +Even though the commands can be associated with a particular module, they
191 +are run using the permissions of the user that started the daemon (not the
192 +module's uid/gid setting) without any chroot restrictions (even if the
193 +module will/has run chroot()ed).
197 manpagesection(AUTHENTICATION STRENGTH)