Don't allow a configure file which is writeable by the Exim user or group
[exim.git] / src / src / readconf.c
index 6fd0dd8ea975095d234aec2be9ebfad69ba293a3..08030583409e77ffeedbd66ffd6a718e41b3d4c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.42 2010/06/07 07:09:10 pdp Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.45 2010/06/12 17:56:32 jetmore Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -399,6 +399,9 @@ static optionlist optionlist_config[] = {
   { "system_filter_reply_transport",opt_stringptr,&system_filter_reply_transport },
   { "system_filter_user",       opt_uid,         &system_filter_uid },
   { "tcp_nodelay",              opt_bool,        &tcp_nodelay },
+#ifdef USE_TCP_WRAPPERS
+  { "tcp_wrappers_daemon_name", opt_stringptr,   &tcp_wrappers_daemon_name },
+#endif
   { "timeout_frozen_after",     opt_time,        &timeout_frozen_after },
   { "timezone",                 opt_stringptr,   &timezone_string },
 #ifdef SUPPORT_TLS
@@ -1516,12 +1519,25 @@ switch (type)
       str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
     if (extra_condition)
       {
-      /* We already have a condition, we're conducting a crude hack to let multiple
-      condition rules be chained together, despite storing them in text form. */
+      /* We already have a condition, we're conducting a crude hack to let
+      multiple condition rules be chained together, despite storing them in
+      text form. */
       saved_condition = *str_target;
-      strtemp = string_sprintf("${if and{{bool{%s}}{bool{%s}}}}",
+      strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
           saved_condition, sptr);
       *str_target = string_copy_malloc(strtemp);
+      /* TODO(pdp): there is a memory leak here when we set 3 or more
+      conditions; I still don't understand the store mechanism enough
+      to know what's the safe way to free content from an earlier store.
+      AFAICT, stores stack, so freeing an early stored item also stores
+      all data alloc'd after it.  If we knew conditions were adjacent,
+      we could survive that, but we don't.  So I *think* we need to take
+      another bit from opt_type to indicate "malloced"; this seems like
+      quite a hack, especially for this one case.  It also means that
+      we can't ever reclaim the store from the *first* condition.
+
+      Because we only do this once, near process start-up, I'm prepared to
+      let this slide for the time being, even though it rankles.  */
       }
     else
       {
@@ -2867,13 +2883,12 @@ if (!config_changed)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
       big_buffer);
 
-  if ((statbuf.st_uid != root_uid &&             /* owner not root */
-       statbuf.st_uid != exim_uid                /* owner not exim */
+  if ((statbuf.st_uid != root_uid                /* owner not root */
        #ifdef CONFIGURE_OWNER
        && statbuf.st_uid != config_uid           /* owner not the special one */
        #endif
          ) ||                                    /* or */
-      (statbuf.st_gid != exim_gid                /* group not exim & */
+      (statbuf.st_gid != root_gid                /* group not root & */
        #ifdef CONFIGURE_GROUP
        && statbuf.st_gid != config_gid           /* group not the special one */
        #endif
@@ -3191,12 +3206,12 @@ if (openssl_options != NULL)
   {
 # ifdef USE_GNUTLS
   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
-    "openssl_options is set but we're using GnuTLS\n");
+    "openssl_options is set but we're using GnuTLS");
 # else
   long dummy;
   if (!(tls_openssl_options_parse(openssl_options, &dummy)))
     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
-      "openssl_options parse error: %s\n", openssl_options);
+      "openssl_options parse error: %s", openssl_options);
 # endif
   }
 #endif