Commit | Line | Data |
---|---|---|
91cad04a | 1 | A fairly decent attempt to add two new daemon module options: |
1955c4a2 | 2 | |
91cad04a WD |
3 | prexfer-exec = COMMAND |
4 | postxfer-exec = COMMAND | |
1955c4a2 | 5 | |
91cad04a WD |
6 | The prexfer-exec command runs before the transfer happens, while the |
7 | postxfer-exec command runs after the transfer completes, even if the | |
8 | transfer failed. The following environment variables will be set in | |
9 | both cases: | |
1955c4a2 | 10 | |
314e606b WD |
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. | |
1955c4a2 | 16 | |
91cad04a WD |
17 | These environment variables will also be set for the postxfer-exec |
18 | command: | |
1955c4a2 | 19 | |
314e606b WD |
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(). | |
91cad04a WD |
25 | |
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). | |
29 | ||
30 | BUILD NOTE: You'll want to run "make proto" after applying this patch. | |
31 | ||
32 | --- orig/clientserver.c 2005-06-10 21:33:27 | |
314e606b | 33 | +++ clientserver.c 2005-07-19 21:17:22 |
91cad04a WD |
34 | @@ -226,7 +226,7 @@ static int rsync_module(int f_in, int f_ |
35 | char line[MAXPATHLEN]; | |
36 | uid_t uid = (uid_t)-2; /* canonically "nobody" */ | |
37 | gid_t gid = (gid_t)-2; | |
38 | - char *p; | |
39 | + char *p, *s; | |
40 | char *addr = client_addr(f_in); | |
41 | char *host = client_name(f_in); | |
42 | char *name = lp_name(i); | |
314e606b | 43 | @@ -347,6 +347,54 @@ static int rsync_module(int f_in, int f_ |
1955c4a2 | 44 | |
91cad04a | 45 | log_init(); |
1955c4a2 | 46 | |
91cad04a WD |
47 | + s = lp_prexfer_exec(i); |
48 | + p = lp_postxfer_exec(i); | |
49 | + if ((s && *s) || (p && *p)) { | |
314e606b | 50 | + char *modname, *modpath, *hostaddr, *hostname, *username; |
91cad04a | 51 | + int status; |
314e606b WD |
52 | + if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0 |
53 | + || asprintf(&modpath, "RSYNC_MODULE_PATH=%s", lp_path(i)) < 0 | |
54 | + || asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0 | |
55 | + || asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0 | |
56 | + || asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0) | |
91cad04a WD |
57 | + out_of_memory("rsync_module"); |
58 | + putenv(modname); | |
91cad04a | 59 | + putenv(modpath); |
314e606b WD |
60 | + putenv(hostaddr); |
61 | + putenv(hostname); | |
62 | + putenv(username); | |
91cad04a WD |
63 | + if (s && *s) { |
64 | + status = system(s); | |
65 | + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { | |
66 | + rprintf(FLOG, "prexfer-exec failed\n"); | |
67 | + io_printf(f_out, "@ERROR: prexfer-exec failed\n"); | |
68 | + return -1; | |
69 | + } | |
70 | + } | |
1955c4a2 | 71 | + if (p && *p) { |
91cad04a WD |
72 | + pid_t pid = fork(); |
73 | + if (pid < 0) { | |
74 | + rsyserr(FLOG, errno, "fork failed"); | |
75 | + io_printf(f_out, "@ERROR: fork failed\n"); | |
76 | + return -1; | |
77 | + } | |
78 | + if (pid) { | |
79 | + char *ret1, *ret2; | |
80 | + waitpid(pid, &status, 0); | |
81 | + if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0) | |
82 | + putenv(ret1); | |
83 | + if (WIFEXITED(status)) | |
84 | + status = WEXITSTATUS(status); | |
85 | + else | |
86 | + status = -1; | |
87 | + if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0) | |
88 | + putenv(ret2); | |
89 | + system(p); | |
90 | + _exit(0); | |
91 | + } | |
1955c4a2 WD |
92 | + } |
93 | + } | |
1955c4a2 WD |
94 | + |
95 | if (use_chroot) { | |
96 | /* | |
97 | * XXX: The 'use chroot' flag is a fairly reliable | |
5b36b3cc | 98 | --- orig/loadparm.c 2005-06-10 21:33:28 |
91cad04a | 99 | +++ loadparm.c 2005-07-19 20:05:26 |
1955c4a2 WD |
100 | @@ -140,6 +140,8 @@ typedef struct |
101 | char *log_format; | |
102 | char *refuse_options; | |
103 | char *dont_compress; | |
91cad04a WD |
104 | + char *prexfer_exec; |
105 | + char *postxfer_exec; | |
1955c4a2 WD |
106 | int timeout; |
107 | int max_connections; | |
108 | int max_verbosity; | |
109 | @@ -175,6 +177,8 @@ static service sDefault = | |
110 | "%o %h [%a] %m (%u) %f %l", /* log format */ | |
111 | NULL, /* refuse options */ | |
112 | "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */ | |
91cad04a WD |
113 | + NULL, /* prexfer_exec */ |
114 | + NULL, /* postxfer_exec */ | |
1955c4a2 WD |
115 | 0, /* timeout */ |
116 | 0, /* max connections */ | |
117 | 1, /* max verbosity */ | |
118 | @@ -298,6 +302,8 @@ static struct parm_struct parm_table[] = | |
119 | {"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0}, | |
120 | {"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0}, | |
121 | {"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0}, | |
91cad04a WD |
122 | + {"prexfer-exec", P_STRING, P_LOCAL, &sDefault.prexfer_exec, NULL, 0}, |
123 | + {"postxfer-exec", P_STRING, P_LOCAL, &sDefault.postxfer_exec,NULL, 0}, | |
1955c4a2 WD |
124 | {NULL, P_BOOL, P_NONE, NULL, NULL, 0} |
125 | }; | |
126 | ||
127 | @@ -379,6 +385,8 @@ FN_LOCAL_STRING(lp_include_from, include | |
128 | FN_LOCAL_STRING(lp_log_format, log_format) | |
129 | FN_LOCAL_STRING(lp_refuse_options, refuse_options) | |
130 | FN_LOCAL_STRING(lp_dont_compress, dont_compress) | |
91cad04a WD |
131 | +FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec) |
132 | +FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec) | |
1955c4a2 WD |
133 | FN_LOCAL_INTEGER(lp_timeout, timeout) |
134 | FN_LOCAL_INTEGER(lp_max_connections, max_connections) | |
135 | FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity) |