./configure (optional if already run)
make
+based-on: a01e3b490eb36ccf9e704840e1b6683dab867550
diff --git a/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -67,6 +67,7 @@ char *auth_user;
+@@ -66,6 +66,7 @@ extern iconv_t ic_send, ic_recv;
+ char *auth_user;
int read_only = 0;
int module_id = -1;
- int munge_symlinks = 0;
+pid_t namecvt_pid = 0;
struct chmod_mode_struct *daemon_chmod_modes;
/* module_dirlen is the length of the module_dir string when in daemon
-@@ -76,6 +77,7 @@ char *module_dir = NULL;
- unsigned int module_dirlen = 0;
+@@ -77,6 +78,7 @@ unsigned int module_dirlen = 0;
+ char *full_module_path;
static int rl_nulls = 0;
+static int namecvt_fd_req = -1, namecvt_fd_ans = -1;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
-@@ -555,7 +557,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -668,7 +670,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
log_init(1);
#ifdef HAVE_PUTENV
- if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
+ if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i) || *lp_name_converter(i)) {
- char *modname, *modpath, *hostaddr, *hostname, *username;
int status;
-@@ -651,6 +653,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+ umask(orig_umask);
+@@ -740,6 +742,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
set_blocking(fds[1]);
pre_exec_fd = fds[1];
}
umask(0);
}
#endif
-@@ -880,6 +920,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -971,6 +1011,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
return 0;
}
diff --git a/loadparm.c b/loadparm.c
--- a/loadparm.c
+++ b/loadparm.c
-@@ -140,6 +140,7 @@ typedef struct
+@@ -122,6 +122,7 @@ typedef struct {
char *log_file;
char *log_format;
char *name;
char *outgoing_chmod;
char *path;
char *postxfer_exec;
-@@ -191,6 +192,7 @@ static service sDefault =
+@@ -196,6 +197,7 @@ static const all_vars Defaults = {
/* log_file; */ NULL,
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
/* name; */ NULL,
/* outgoing_chmod; */ NULL,
/* path; */ NULL,
/* postxfer_exec; */ NULL,
-@@ -328,6 +330,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},
- {"numeric ids", P_BOOL, P_LOCAL, &sDefault.numeric_ids, NULL,0},
- {"outgoing chmod", P_STRING, P_LOCAL, &sDefault.outgoing_chmod, NULL,0},
- {"path", P_PATH, P_LOCAL, &sDefault.path, NULL,0},
-@@ -418,6 +421,7 @@ FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
+@@ -338,6 +340,7 @@ static struct parm_struct parm_table[] =
+ {"max verbosity", P_INTEGER,P_LOCAL, &Vars.l.max_verbosity, NULL,0},
+ {"munge symlinks", P_BOOL, P_LOCAL, &Vars.l.munge_symlinks, NULL,0},
+ {"name", P_STRING, P_LOCAL, &Vars.l.name, NULL,0},
++ {"name converter", P_STRING, P_LOCAL, &Vars.l.name_converter, NULL,0},
+ {"numeric ids", P_BOOL, P_LOCAL, &Vars.l.numeric_ids, NULL,0},
+ {"outgoing chmod", P_STRING, P_LOCAL, &Vars.l.outgoing_chmod, NULL,0},
+ {"path", P_PATH, P_LOCAL, &Vars.l.path, NULL,0},
+@@ -465,6 +468,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)
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
-@@ -160,10 +160,11 @@ if the module is not read-only).
+@@ -183,10 +183,11 @@ if the module is not read-only).
- When this option is enabled, rsync will not attempt to map users and groups
+ When this parameter is enabled, rsync will not attempt to map users and groups
by name (by default), but instead copy IDs as though bf(--numeric-ids) had
-been specified. In order to enable name-mapping, rsync needs to be able to
+been specified. In order to enable name-mapping, rsync needs either the
process in the chroot hierarchy will need to have access to the resources
used by these library functions (traditionally /etc/passwd and
/etc/group, but perhaps additional dynamic libraries as well).
-@@ -227,6 +228,27 @@ path elements that rsync believes will allow a symlink to escape the module's
+@@ -252,6 +253,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.
+ better trust your users if you choose this combination of parameters.
-+dit(bf(name converter)) The "name converter" option lets you specify a
++dit(bf(name converter)) This parameter 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
++that parameter 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
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;
+@@ -30,6 +30,7 @@ mode_t orig_umask = 002;
+ char number_separator = ',';
char *partial_dir;
char *module_dir;
+pid_t namecvt_pid;
- struct filter_list_struct daemon_filter_list;
+ filter_rule_list daemon_filter_list;
void rprintf(UNUSED(enum logcode code), const char *format, ...)
-@@ -69,6 +70,11 @@ struct filter_list_struct daemon_filter_list;
+@@ -70,6 +71,11 @@ filter_rule_list daemon_filter_list;
return -1;
}
diff --git a/uidlist.c b/uidlist.c
--- a/uidlist.c
+++ b/uidlist.c
-@@ -32,6 +32,7 @@ extern int preserve_uid;
+@@ -33,6 +33,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
+ extern gid_t our_gid;
+ extern char *usermap;
+ extern char *groupmap;
+@@ -76,8 +77,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)
+ char *uid_to_user(uid_t uid)
{
- struct passwd *pass = getpwuid(uid);
- if (pass)
return strdup(pass->pw_name);
return NULL;
}
-@@ -78,8 +83,12 @@ static const char *uid_to_name(uid_t uid)
+@@ -85,8 +90,12 @@ char *uid_to_user(uid_t uid)
/* turn a gid into a group name */
- static const char *gid_to_name(gid_t gid)
+ char *gid_to_group(gid_t gid)
{
- struct group *grp = getgrgid(gid);
- if (grp)
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 daemon_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)
+@@ -94,32 +103,54 @@ char *gid_to_group(gid_t gid)
+ /* Parse a user name or (optionally) a number into a uid */
+ int user_to_uid(const char *name, uid_t *uid_p, BOOL num_ok)
{
- struct passwd *pass;
+ uid_t uid;
+
if (!name || !*name)
return 0;
++
+ if (num_ok && name[strspn(name, "0123456789")] == '\0') {
+ *uid_p = atol(name);
+ return 1;
+ }
- if (!(pass = getpwnam(name)))
- return 0;
- *uid_p = pass->pw_uid;
return 1;
}
- /** Turn a group name into a gid */
- int name_to_gid(const char *name, gid_t *gid_p)
+ /* Parse a group name or (optionally) a number into a gid */
+ int group_to_gid(const char *name, gid_t *gid_p, BOOL num_ok)
{
- struct group *grp;
+ gid_t gid;
+
if (!name || !*name)
return 0;
++
+ if (num_ok && name[strspn(name, "0123456789")] == '\0') {
+ *gid_p = atol(name);
+ return 1;
+ }
- if (!(grp = getgrnam(name)))
- return 0;
- *gid_p = grp->gr_gid;
return 1;
}
+diff --git a/util.c b/util.c
+--- a/util.c
++++ b/util.c
+@@ -31,9 +31,10 @@ extern int modify_window;
+ extern int relative_paths;
+ extern int preserve_xattrs;
+ 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 filter_rule_list daemon_filter_list;
+
+ int sanitize_paths = 0;