Added the "reverse lookup" daemon-config parameter.
authorMatt McCutchen <matt@mattmccutchen.net>
Thu, 15 Jan 2009 08:07:05 +0000 (00:07 -0800)
committerWayne Davison <wayned@samba.org>
Thu, 15 Jan 2009 08:22:36 +0000 (00:22 -0800)
NEWS
clientserver.c
loadparm.c
log.c
rsyncd.conf.yo

diff --git a/NEWS b/NEWS
index eaacde6..073909e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,9 @@ Changes since 3.0.4:
       MD5 checksum of any transferred file, or all files if --checksum was
       specified (when protocol 30 or above is in effect).
 
+    - Added the "reverse lookup" parameter to the rsync daemon config file to
+      allow reverse-DNS lookups to be disabled.
+
   EXTRAS:
 
     - Added an "instant-rsyncd" script to the support directory, which makes
index 09fd315..1bc5b9a 100644 (file)
@@ -81,6 +81,9 @@ static int rl_nulls = 0;
 static struct sigaction sigact;
 #endif
 
+/* Used when "reverse lookup" is off. */
+const char undetermined_hostname[] = "UNDETERMINED";
+
 /**
  * Run a client connected to an rsyncd.  The alternative to this
  * function for remote-shell connections is do_cmd().
@@ -427,6 +430,11 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
        iconv_opt = NULL;
 #endif
 
+       /* If reverse lookup is disabled globally but enabled for this module,
+        * we need to do it now before the access check. */
+       if (host == undetermined_hostname && lp_reverse_lookup(i))
+               host = client_name(f_in);
+
        if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
                rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
                        name, host, addr);
@@ -927,7 +935,7 @@ int start_daemon(int f_in, int f_out)
                exit_cleanup(RERR_SYNTAX);
 
        addr = client_addr(f_in);
-       host = client_name(f_in);
+       host = lp_reverse_lookup(-1) ? client_name(f_in) : undetermined_hostname;
        rprintf(FLOG, "connect from %s (%s)\n", host, addr);
 
        if (!am_server) {
index f5e1f16..b3197a8 100644 (file)
@@ -149,6 +149,7 @@ typedef struct {
        BOOL munge_symlinks;
        BOOL numeric_ids;
        BOOL read_only;
+       BOOL reverse_lookup;
        BOOL strict_modes;
        BOOL transfer_logging;
        BOOL use_chroot;
@@ -203,6 +204,7 @@ static section sDefault = {
  /* munge_symlinks; */         (BOOL)-1,
  /* numeric_ids; */            (BOOL)-1,
  /* read_only; */              True,
+ /* reverse_lookup; */         True,
  /* strict_modes; */           True,
  /* transfer_logging; */       False,
  /* use_chroot; */             True,
@@ -327,6 +329,7 @@ static struct parm_struct parm_table[] =
 #endif
  {"read only",         P_BOOL,   P_LOCAL, &sDefault.read_only,         NULL,0},
  {"refuse options",    P_STRING, P_LOCAL, &sDefault.refuse_options,    NULL,0},
+ {"reverse lookup",    P_BOOL,   P_LOCAL, &sDefault.reverse_lookup,    NULL,0},
  {"secrets file",      P_STRING, P_LOCAL, &sDefault.secrets_file,      NULL,0},
  {"strict modes",      P_BOOL,   P_LOCAL, &sDefault.strict_modes,      NULL,0},
  {"syslog facility",   P_ENUM,   P_LOCAL, &sDefault.syslog_facility,enum_facilities,0},
@@ -417,6 +420,7 @@ FN_LOCAL_BOOL(lp_list, list)
 FN_LOCAL_BOOL(lp_munge_symlinks, munge_symlinks)
 FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
 FN_LOCAL_BOOL(lp_read_only, read_only)
+FN_LOCAL_BOOL(lp_reverse_lookup, reverse_lookup)
 FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
 FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
 FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
diff --git a/log.c b/log.c
index 551cb06..adde3c8 100644 (file)
--- a/log.c
+++ b/log.c
@@ -60,6 +60,7 @@ extern char curr_dir[MAXPATHLEN];
 extern char *full_module_path;
 extern unsigned int module_dirlen;
 extern char sender_file_sum[MAX_DIGEST_LEN];
+extern const char undetermined_hostname[];
 
 static int log_initialised;
 static int logfile_was_closed;
@@ -503,10 +504,16 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
                *c = '\0';
                n = NULL;
 
+               /* Note for %h and %a: it doesn't matter what fd we pass to
+                * client_{name,addr} because rsync_module will already have
+                * forced the answer to be cached (assuming, of course, for %h
+                * that lp_reverse_lookup(module_id) is true). */
                switch (*p) {
                case 'h':
-                       if (am_daemon)
-                               n = client_name(0);
+                       if (am_daemon) {
+                               n = lp_reverse_lookup(module_id)
+                                 ? client_name(0) : undetermined_hostname;
+                       }
                        break;
                case 'a':
                        if (am_daemon)
index 06768e9..992b7ce 100644 (file)
@@ -304,10 +304,14 @@ attempted downloads will fail. If "write only" is false then downloads
 will be possible if file permissions on the daemon side allow them.  The
 default is for this parameter to be disabled.
 
-dit(bf(list)) This parameter determines if this module should be
-listed when the client asks for a listing of available modules. By
-setting this to false you can create hidden modules. The default is
-for modules to be listable.
+dit(bf(list)) This parameter determines whether this module is
+listed when the client asks for a listing of available modules.  In addition,
+if this is false, the daemon will pretend the module does not exist
+when a client denied by "hosts allow" or "hosts deny" attempts to access it.
+Realize that if "reverse lookup" is disabled globally but enabled for the
+module, the resulting reverse lookup to a potentially client-controlled DNS
+server may still reveal to the client that it hit an existing module.
+The default is for modules to be listable.
 
 dit(bf(uid)) This parameter specifies the user name or user ID that
 file transfers to and from that module should take place as when the daemon
@@ -450,7 +454,8 @@ quote(itemization(
   addresses which match the masked IP address will be allowed in.
   it() a hostname. The hostname as determined by a reverse lookup will
   be matched (case insensitive) against the pattern. Only an exact
-  match is allowed in.
+  match is allowed in.  This only works if "reverse lookup" is enabled
+  (the default).
   it() a hostname pattern using wildcards. These are matched using the
   same rules as normal unix filename matching. If the pattern matches
   then the client is allowed in.
@@ -481,6 +486,18 @@ rejected. See the "hosts allow" parameter for more information.
 
 The default is no "hosts deny" parameter, which means all hosts can connect.
 
+dit(bf(reverse lookup)) Controls whether the daemon performs a reverse lookup
+on the client's IP address to determine its hostname, which is used for
+"hosts allow"/"hosts deny" checks and the "%h" log escape.  This is enabled by
+default, but you may wish to disable it to save time if you know the lookup will
+not return a useful result, in which case the daemon will use the name
+"UNDETERMINED" instead.
+
+If this parameter is enabled globally (even by default), rsync performs the
+lookup as soon as a client connects, so disabling it for a module will not
+avoid the lookup.  Thus, you probably want to disable it globally and then
+enable it for modules that need the information.
+
 dit(bf(ignore errors)) This parameter tells rsyncd to
 ignore I/O errors on the daemon when deciding whether to run the delete
 phase of the transfer. Normally rsync skips the bf(--delete) step if any