#include "exim.h"
+extern void init_lookup_list(void);
+
/*************************************************
#endif
fprintf(f, "\n");
-fprintf(f, "Lookups:");
-#ifdef LOOKUP_LSEARCH
+fprintf(f, "Lookups (built-in):");
+#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
fprintf(f, " lsearch wildlsearch nwildlsearch iplsearch");
#endif
-#ifdef LOOKUP_CDB
+#if defined(LOOKUP_CDB) && LOOKUP_CDB!=2
fprintf(f, " cdb");
#endif
-#ifdef LOOKUP_DBM
+#if defined(LOOKUP_DBM) && LOOKUP_DBM!=2
fprintf(f, " dbm dbmnz");
#endif
-#ifdef LOOKUP_DNSDB
+#if defined(LOOKUP_DNSDB) && LOOKUP_DNSDB!=2
fprintf(f, " dnsdb");
#endif
-#ifdef LOOKUP_DSEARCH
+#if defined(LOOKUP_DSEARCH) && LOOKUP_DSEARCH!=2
fprintf(f, " dsearch");
#endif
-#ifdef LOOKUP_IBASE
+#if defined(LOOKUP_IBASE) && LOOKUP_IBASE!=2
fprintf(f, " ibase");
#endif
-#ifdef LOOKUP_LDAP
+#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
fprintf(f, " ldap ldapdn ldapm");
#endif
-#ifdef LOOKUP_MYSQL
+#if defined(LOOKUP_MYSQL) && LOOKUP_MYSQL!=2
fprintf(f, " mysql");
#endif
-#ifdef LOOKUP_NIS
+#if defined(LOOKUP_NIS) && LOOKUP_NIS!=2
fprintf(f, " nis nis0");
#endif
-#ifdef LOOKUP_NISPLUS
+#if defined(LOOKUP_NISPLUS) && LOOKUP_NISPLUS!=2
fprintf(f, " nisplus");
#endif
-#ifdef LOOKUP_ORACLE
+#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
fprintf(f, " oracle");
#endif
-#ifdef LOOKUP_PASSWD
+#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
fprintf(f, " passwd");
#endif
-#ifdef LOOKUP_PGSQL
+#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
fprintf(f, " pgsql");
#endif
-#ifdef LOOKUP_SQLITE
+#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
fprintf(f, " sqlite");
#endif
-#ifdef LOOKUP_TESTDB
+#if defined(LOOKUP_TESTDB) && LOOKUP_TESTDB!=2
fprintf(f, " testdb");
#endif
-#ifdef LOOKUP_WHOSON
+#if defined(LOOKUP_WHOSON) && LOOKUP_WHOSON!=2
fprintf(f, " whoson");
#endif
fprintf(f, "\n");
#ifdef SUPPORT_TLS
tls_version_report(f);
#endif
+
+/* Everything else is details which are only worth reporting when debugging.
+Perhaps the tls_version_report should move into this too. */
+DEBUG(D_any) do {
+
+ int i;
+
+#ifdef AUTH_CYRUS_SASL
+ auth_cyrus_sasl_version_report(f);
+#endif
+
+ fprintf(f, "Library version: PCRE: Compile: %d.%d%s\n"
+ " Runtime: %s\n",
+ PCRE_MAJOR, PCRE_MINOR,
+ /* PRE_PRERELEASE is either defined and empty or a string.
+ * This should work: */
+ PCRE_PRERELEASE "",
+ pcre_version());
+
+ init_lookup_list();
+ for (i = 0; i < lookup_list_count; i++)
+ {
+ if (lookup_list[i]->version_report)
+ lookup_list[i]->version_report(f);
+ }
+
+} while (0);
}
int filter_sfd = -1;
int filter_ufd = -1;
int group_count;
-int i;
+int i, rv;
int list_queue_option = 0;
int msg_action = 0;
int msg_action_arg = -1;
if (real_uid == root_uid)
{
- setgid(real_gid);
- setuid(real_uid);
+ rv = setgid(real_gid);
+ if (rv)
+ {
+ fprintf(stderr, "exim: setgid(%ld) failed: %s\n",
+ (long int)real_gid, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ rv = setuid(real_uid);
+ if (rv)
+ {
+ fprintf(stderr, "exim: setuid(%ld) failed: %s\n",
+ (long int)real_uid, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
}
/* If neither the original real uid nor the original euid was root, Exim is
#endif
if (real_uid != root_uid)
{
- #ifdef TRUSTED_CONFIG_PREFIX_LIST
+ #ifdef TRUSTED_CONFIG_LIST
- if (Ustrstr(argrest, "/../"))
+ if (real_uid != exim_uid
+ #ifdef CONFIGURE_OWNER
+ && real_uid != config_uid
+ #endif
+ )
trusted_config = FALSE;
else
{
- FILE *trust_list = Ufopen(TRUSTED_CONFIG_PREFIX_LIST, "rb");
+ FILE *trust_list = Ufopen(TRUSTED_CONFIG_LIST, "rb");
if (trust_list)
{
struct stat statbuf;
{
/* Well, the trust list at least is up to scratch... */
void *reset_point = store_get(0);
- uschar *trusted_prefixes[32];
- int nr_prefixes = 0;
+ uschar *trusted_configs[32];
+ int nr_configs = 0;
int i = 0;
while (Ufgets(big_buffer, big_buffer_size, trust_list))
nl = Ustrchr(start, '\n');
if (nl)
*nl = 0;
- trusted_prefixes[nr_prefixes++] = string_copy(start);
- if (nr_prefixes == 32)
+ trusted_configs[nr_configs++] = string_copy(start);
+ if (nr_configs == 32)
break;
}
fclose(trust_list);
- if (nr_prefixes)
+ if (nr_configs)
{
int sep = 0;
uschar *list = argrest;
while (trusted_config && (filename = string_nextinlist(&list,
&sep, big_buffer, big_buffer_size)) != NULL)
{
- for (i=0; i < nr_prefixes; i++)
+ for (i=0; i < nr_configs; i++)
{
- int len = Ustrlen(trusted_prefixes[i]);
- if (Ustrlen(filename) >= len &&
- Ustrncmp(filename, trusted_prefixes[i], len) == 0)
+ if (Ustrcmp(filename, trusted_configs[i]) == 0)
break;
}
- if (i == nr_prefixes)
+ if (i == nr_configs)
{
trusted_config = FALSE;
break;
debug_printf("Exim version %s uid=%ld gid=%ld pid=%d D=%x\n",
version_string, (long int)real_uid, (long int)real_gid, (int)getpid(),
debug_selector);
- show_whats_supported(stderr);
+ if (!version_printed)
+ show_whats_supported(stderr);
}
}
else
log_write(0, LOG_MAIN|LOG_PANIC,
"exim user lost privilege for using %s option",
- (int)exim_uid, trusted_config? "-D" : "-C");
+ trusted_config? "-D" : "-C");
}
/* Start up Perl interpreter if Perl support is configured and there is a
}
#endif /* EXIM_PERL */
+/* Initialise lookup_list
+If debugging, already called above via version reporting.
+This does mean that debugging causes the list to be initialised while root.
+This *should* be harmless -- all modules are loaded from a fixed dir and
+it's code that would, if not a module, be part of Exim already. */
+init_lookup_list();
+
/* Log the arguments of the call if the configuration file said so. This is
a debugging feature for finding out what arguments certain MUAs actually use.
Don't attempt it if logging is disabled, or if listing variables or if
/* When we are retaining a privileged uid, we still change to the exim gid. */
-else setgid(exim_gid);
+else
+ {
+ int rv;
+ rv = setgid(exim_gid);
+ /* Impact of failure is that some stuff might end up with an incorrect group.
+ We track this for failures from root, since any attempt to change privilege
+ by root should succeed and failures should be examined. For non-root,
+ there's no security risk. For me, it's { exim -bV } on a just-built binary,
+ no need to complain then. */
+ if (rv == -1)
+ {
+ if (!unprivileged)
+ {
+ fprintf(stderr,
+ "exim: changing group failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ else
+ debug_printf("changing group to %ld failed: %s\n",
+ (long int)exim_gid, strerror(errno));
+ }
+ }
/* Handle a request to scan a file for malware */
if (malware_test_file)