Tweaked a couple sentences.
[rsync/rsync-patches.git] / nameconverter.diff
index 2f428c8..73b2cf0 100644 (file)
@@ -20,35 +20,36 @@ To use this patch, run these commands for a successful build:
     ./configure                         (optional if already run)
     make
 
     ./configure                         (optional if already run)
     make
 
+based-on: 3b8f8192227b14e708bf535072485e50f4362270
 diff --git a/clientserver.c b/clientserver.c
 --- a/clientserver.c
 +++ b/clientserver.c
 diff --git a/clientserver.c b/clientserver.c
 --- a/clientserver.c
 +++ b/clientserver.c
-@@ -59,6 +59,7 @@ char *auth_user;
+@@ -67,6 +67,7 @@ extern iconv_t ic_send, ic_recv;
+ char *auth_user;
  int read_only = 0;
  int module_id = -1;
  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
 +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
-@@ -67,6 +68,7 @@ char *module_dir = NULL;
unsigned int module_dirlen = 0;
+@@ -78,6 +79,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;
  
  static int rl_nulls = 0;
 +static int namecvt_fd_req = -1, namecvt_fd_ans = -1;
  
  #ifdef HAVE_SIGACTION
  static struct sigaction sigact;
-@@ -508,7 +510,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -669,7 +671,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)) {
        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;
                int status;
-               if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
-@@ -595,6 +597,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+               umask(orig_umask);
+@@ -741,6 +743,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];
                }
                        set_blocking(fds[1]);
                        pre_exec_fd = fds[1];
                }
@@ -93,7 +94,7 @@ diff --git a/clientserver.c b/clientserver.c
                umask(0);
        }
  #endif
                umask(0);
        }
  #endif
-@@ -789,6 +829,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -968,6 +1008,44 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        return 0;
  }
  
        return 0;
  }
  
@@ -141,7 +142,7 @@ diff --git a/clientserver.c b/clientserver.c
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
 diff --git a/loadparm.c b/loadparm.c
 --- a/loadparm.c
 +++ b/loadparm.c
-@@ -139,6 +139,7 @@ typedef struct
+@@ -122,6 +122,7 @@ typedef struct {
        char *log_file;
        char *log_format;
        char *name;
        char *log_file;
        char *log_format;
        char *name;
@@ -149,7 +150,7 @@ diff --git a/loadparm.c b/loadparm.c
        char *outgoing_chmod;
        char *path;
        char *postxfer_exec;
        char *outgoing_chmod;
        char *path;
        char *postxfer_exec;
-@@ -188,6 +189,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,
   /* log_file; */              NULL,
   /* log_format; */            "%o %h [%a] %m (%u) %f %l",
   /* name; */                  NULL,
@@ -157,44 +158,46 @@ diff --git a/loadparm.c b/loadparm.c
   /* outgoing_chmod; */                NULL,
   /* path; */                  NULL,
   /* postxfer_exec; */         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)
+@@ -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)
 +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_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)
+ FN_LOCAL_STRING(lp_temp_dir, temp_dir)
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
 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).
+@@ -183,10 +183,11 @@ 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
+ 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
++bf(name converter) parameter to specify a conversion program, or it needs to
  use the standard library functions for looking up names and IDs (i.e.
  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
+ code(getpwuid()), code(getgrgid()), code(getpwname()), and code(getgrnam())).
+-This means the rsync
++The latter choice means the rsync
+ 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).
+@@ -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
  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
 +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
 +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
@@ -213,9 +216,9 @@ diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 +bf(RSYNC_USER_NAME).  This is useful if you want to customize the
 +conversion using a single program invocation.
 +
 +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
+ dit(bf(charset)) This specifies the name of the character set in which the
+ module's filenames are stored.  If the client uses an bf(--iconv) option,
+ the daemon will use the value of the "charset" parameter regardless of the
 diff --git a/support/nameconvert b/support/nameconvert
 new file mode 100755
 --- /dev/null
 diff --git a/support/nameconvert b/support/nameconvert
 new file mode 100755
 --- /dev/null
@@ -266,15 +269,15 @@ new file mode 100755
 diff --git a/t_stub.c b/t_stub.c
 --- a/t_stub.c
 +++ b/t_stub.c
 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;
  char *partial_dir;
  char *module_dir;
 +pid_t namecvt_pid;
struct filter_list_struct server_filter_list;
filter_rule_list daemon_filter_list;
  
   void rprintf(UNUSED(enum logcode code), const char *format, ...)
  
   void rprintf(UNUSED(enum logcode code), const char *format, ...)
-@@ -69,6 +70,11 @@ struct filter_list_struct server_filter_list;
+@@ -70,6 +71,11 @@ filter_rule_list daemon_filter_list;
        return -1;
  }
  
        return -1;
  }
  
@@ -289,17 +292,17 @@ diff --git a/t_stub.c b/t_stub.c
 diff --git a/uidlist.c b/uidlist.c
 --- a/uidlist.c
 +++ b/uidlist.c
 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;
  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 */
  /* 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)
  {
 -      struct passwd *pass = getpwuid(uid);
 -      if (pass)
@@ -312,9 +315,9 @@ diff --git a/uidlist.c b/uidlist.c
                return strdup(pass->pw_name);
        return NULL;
  }
                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 */
  /* 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)
  {
 -      struct group *grp = getgrgid(gid);
 -      if (grp)
@@ -327,30 +330,20 @@ diff --git a/uidlist.c b/uidlist.c
                return strdup(grp->gr_name);
        return 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)
+@@ -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;
  {
 -      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;
 -      if (!(pass = getpwnam(name)))
 -              return 0;
 -      *uid_p = pass->pw_uid;
@@ -369,14 +362,19 @@ diff --git a/util.c b/util.c
        return 1;
  }
  
        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;
  {
 -      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;
 -      if (!(grp = getgrnam(name)))
 -              return 0;
 -      *gid_p = grp->gr_gid;
@@ -395,3 +393,18 @@ diff --git a/util.c b/util.c
        return 1;
  }
  
        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;