X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Freadconf.c;h=f4a9b2d2333ff029d6d277528eb0751f5afff28c;hb=5fb822fc4839e253d2f839ba7966bc25a5329ac1;hp=ead74c1d039c41a0811b06b111183b16ff6619b5;hpb=d1af83598f7d6b32516a11bb28e569d592a05c48;p=exim.git diff --git a/src/src/readconf.c b/src/src/readconf.c index ead74c1d0..f4a9b2d23 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for reading the configuration file, and for displaying @@ -16,7 +16,7 @@ extern char **environ; static void fn_smtp_receive_timeout(const uschar * name, const uschar * str); static void save_config_line(const uschar* line); static void save_config_position(const uschar *file, int line); -static void print_config(BOOL admin); +static void print_config(BOOL admin, BOOL terse); #define CSTATE_STACK_SIZE 10 @@ -271,11 +271,6 @@ static optionlist optionlist_config[] = { #ifdef SUPPORT_TLS { "gnutls_allow_auto_pkcs11", opt_bool, &gnutls_allow_auto_pkcs11 }, { "gnutls_compat_mode", opt_bool, &gnutls_compat_mode }, - /* These three gnutls_require_* options stopped working in Exim 4.80 */ - /* From 4.83 we log a warning; a future relase will remove them */ - { "gnutls_require_kx", opt_stringptr, &gnutls_require_kx }, - { "gnutls_require_mac", opt_stringptr, &gnutls_require_mac }, - { "gnutls_require_protocols", opt_stringptr, &gnutls_require_proto }, #endif { "header_line_maxsize", opt_int, &header_line_maxsize }, { "header_maxsize", opt_int, &header_maxsize }, @@ -349,6 +344,7 @@ static optionlist optionlist_config[] = { #ifdef EXIM_PERL { "perl_at_start", opt_bool, &opt_perl_at_start }, { "perl_startup", opt_stringptr, &opt_perl_startup }, + { "perl_taintmode", opt_bool, &opt_perl_taintmode }, #endif #ifdef LOOKUP_PGSQL { "pgsql_servers", opt_stringptr, &pgsql_servers }, @@ -2039,6 +2035,7 @@ switch (type) /* Integer held in K: again, allow octal and hex formats, and suffixes K and M. */ + /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */ case opt_Kint: { @@ -2648,7 +2645,7 @@ if (type == NULL) if (Ustrcmp(name, "config") == 0) { - print_config(admin_user); + print_config(admin_user, no_labels); return; } @@ -2707,16 +2704,15 @@ if (type == NULL) { if (environ) { - uschar **p; - size_t n; + uschar ** p; for (p = USS environ; *p; p++) ; - n = p - USS environ; qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer); for (p = USS environ; *p; p++) { - if (no_labels) *(Ustrchr(*p, '=')) = '\0'; - puts(*p); + uschar * q; + if (no_labels && (q = Ustrchr(*p, '='))) *q = '\0'; + puts(CS *p); } } return; @@ -2947,7 +2943,7 @@ Returns: bool for "okay"; false will cause caller to immediately exit. #ifdef SUPPORT_TLS static BOOL -tls_dropprivs_validate_require_cipher(void) +tls_dropprivs_validate_require_cipher(BOOL nowarn) { const uschar *errmsg; pid_t pid; @@ -2961,9 +2957,9 @@ if ( !tls_advertise_hosts || Ustrcmp(tls_advertise_hosts, ":") == 0 ) return TRUE; -else if (!tls_certificate) - log_write(0, LOG_MAIN|LOG_PANIC, - "Warning: No server certificate defined; TLS connections will fail.\n" +else if (!nowarn && !tls_certificate) + log_write(0, LOG_MAIN, + "Warning: No server certificate defined; will use a selfsigned one.\n" " Suggested action: either install a certificate or change tls_advertise_hosts option"); oldsignal = signal(SIGCHLD, SIG_DFL); @@ -3035,7 +3031,7 @@ systems. Therefore they are available only when requested by compile-time options. */ void -readconf_main(void) +readconf_main(BOOL nowarn) { int sep = 0; struct stat statbuf; @@ -3048,14 +3044,6 @@ while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)) != NULL) { - /* To avoid confusion: Exim changes to / at the very beginning and - * and to $spool_directory later. */ - if (filename[0] != '/') - { - fprintf(stderr, "-C %s: only absolute names are allowed\n", filename); - exit(EXIT_FAILURE); - } - /* Cut out all the fancy processing unless specifically wanted */ #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID) @@ -3109,6 +3097,15 @@ while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)) if (config_file != NULL || errno != ENOENT) break; } +/* Now, once we found and opened our configuration file, we change the directory +to a safe place. Later we change to $spool_directory. */ + +if (Uchdir("/") < 0) + { + perror("exim: chdir `/': "); + exit(EXIT_FAILURE); + } + /* On success, save the name for verification; config_filename is used when logging configuration errors (it changes for .included files) whereas config_main_filename is the name shown by -bP. Failure to open a configuration @@ -3472,7 +3469,7 @@ if ((tls_verify_hosts != NULL || tls_try_verify_hosts != NULL) && /* This also checks that the library linkage is working and we can call routines in it, so call even if tls_require_ciphers is unset */ -if (!tls_dropprivs_validate_require_cipher()) +if (!tls_dropprivs_validate_require_cipher(nowarn)) exit(1); /* Magic number: at time of writing, 1024 has been the long-standing value @@ -3495,17 +3492,12 @@ if (openssl_options != NULL) "openssl_options parse error: %s", openssl_options); # endif } - -if (gnutls_require_kx || gnutls_require_mac || gnutls_require_proto) - log_write(0, LOG_MAIN, "WARNING: main options" - " gnutls_require_kx, gnutls_require_mac and gnutls_require_protocols" - " are obsolete\n"); #endif /*SUPPORT_TLS*/ -if ((!add_environment || *add_environment == '\0') && !keep_environment) +if (!nowarn && !keep_environment && environ && *environ) log_write(0, LOG_MAIN, - "WARNING: purging the environment.\n" - " Suggested action: use keep_environment and add_environment.\n"); + "Warning: purging the environment.\n" + " Suggested action: use keep_environment."); } @@ -3618,9 +3610,9 @@ while ((buffer = get_config_line()) != NULL) if (isupper(*name) && *s == '=') { - if (d != NULL) + if (d) { - if (d->driver_name == NULL) + if (!d->driver_name) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no driver defined for %s \"%s\"", class, d->name); (d->info->init)(d); @@ -3640,9 +3632,9 @@ while ((buffer = get_config_line()) != NULL) /* Finish off initializing the previous driver. */ - if (d != NULL) + if (d) { - if (d->driver_name == NULL) + if (!d->driver_name) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no driver defined for %s \"%s\"", class, d->name); (d->info->init)(d); @@ -3650,7 +3642,7 @@ while ((buffer = get_config_line()) != NULL) /* Check that we haven't already got a driver of this name */ - for (d = *anchor; d != NULL; d = d->next) + for (d = *anchor; d; d = d->next) if (Ustrcmp(name, d->name) == 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "there are two %ss called \"%s\"", class, name); @@ -3661,7 +3653,7 @@ while ((buffer = get_config_line()) != NULL) d = store_get(instance_size); memcpy(d, instance_default, instance_size); *p = d; - p = &(d->next); + p = &d->next; d->name = string_copy(name); /* Clear out the "set" bits in the generic options */ @@ -3679,8 +3671,8 @@ while ((buffer = get_config_line()) != NULL) /* Not the start of a new driver. Give an error if we have not set up a current driver yet. */ - if (d == NULL) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, - "%s name missing", class); + if (!d) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s name missing", class); /* First look to see if this is a generic option; if it is "driver", initialize the driver. If is it not a generic option, we can look for a @@ -3689,7 +3681,7 @@ while ((buffer = get_config_line()) != NULL) if (readconf_handle_option(buffer, driver_optionlist, driver_optionlist_count, d, NULL)) { - if (d->info == NULL && d->driver_name != NULL) + if (!d->info && d->driver_name) init_driver(d, drivers_available, size_of_info, class); } @@ -3697,11 +3689,9 @@ while ((buffer = get_config_line()) != NULL) live therein. A flag with each option indicates if it is in the public block. */ - else if (d->info != NULL) - { + else if (d->info) readconf_handle_option(buffer, d->info->options, *(d->info->options_count), d, US"option \"%s\" unknown"); - } /* The option is not generic and the driver name has not yet been given. */ @@ -3711,9 +3701,9 @@ while ((buffer = get_config_line()) != NULL) /* Run the initialization function for the final driver. */ -if (d != NULL) +if (d) { - if (d->driver_name == NULL) + if (!d->driver_name) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no driver defined for %s \"%s\"", class, d->name); (d->info->init)(d); @@ -4072,22 +4062,19 @@ readconf_driver_init(US"authenticator", optionlist_auths, /* generic options */ optionlist_auths_size); -for (au = auths; au != NULL; au = au->next) +for (au = auths; au; au = au->next) { - if (au->public_name == NULL) + if (!au->public_name) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no public name specified for " "the %s authenticator", au->name); - for (bu = au->next; bu != NULL; bu = bu->next) - { + + for (bu = au->next; bu; bu = bu->next) if (strcmpic(au->public_name, bu->public_name) == 0) - { if ((au->client && bu->client) || (au->server && bu->server)) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "two %s authenticators " "(%s and %s) have the same public name (%s)", - (au->client)? US"client" : US"server", au->name, bu->name, + au->client ? US"client" : US"server", au->name, bu->name, au->public_name); - } - } } } @@ -4307,10 +4294,10 @@ current = next; /* List the parsed config lines, care about nice formatting and hide the values unless we're the admin user */ void -print_config(BOOL admin) +print_config(BOOL admin, BOOL terse) { config_line_item *i; -const int TS = 2; +const int TS = terse ? 0 : 2; int indent = 0; for (i = config_lines; i; i = i->next) @@ -4350,7 +4337,7 @@ for (i = config_lines; i; i = i->next) /* begin lines are left aligned */ else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5])) { - puts(""); + if (!terse) puts(""); puts(CCS current); indent = TS; } @@ -4358,7 +4345,8 @@ for (i = config_lines; i; i = i->next) /* router/acl/transport block names */ else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '=')) { - printf("\n%*s%s\n", TS, "", current); + if (!terse) puts(""); + printf("%*s%s\n", TS, "", current); indent = 2 * TS; }