diff --git a/opendkim/config.c b/opendkim/config.c index b685f654..bd4b1d75 100644 --- a/opendkim/config.c +++ b/opendkim/config.c @@ -173,6 +173,7 @@ config_attach(struct config *c1, struct config **c2) ** outpath -- configuration file in which error occurred (updated) ** outpathlen -- bytes available at "outpath" ** level -- nesting level +** deprecated -- string containing list of deprecated items (updated) ** ** Return value: ** Pointer to a (struct config) which is the head of a list of @@ -186,7 +187,7 @@ config_attach(struct config *c1, struct config **c2) static struct config * config_load_level(char *file, struct configdef *def, unsigned int *line, char *outpath, size_t outpathlen, - int level) + int level, char **deprecated) { int n = -1; int err = 0; @@ -287,6 +288,38 @@ config_load_level(char *file, struct configdef *def, switch (def[n].cd_type) { + case CONFIG_TYPE_DEPRECATED: + if (deprecated == NULL) + { + break; + } + else if (*deprecated == NULL) + { + *deprecated = strdup(def[n].cd_name); + } + else + { + char *new; + size_t oldlen; + size_t newlen; + + oldlen = strlen(*deprecated); + newlen = oldlen + 2 + + strlen(def[n].cd_name); + new = realloc(*deprecated, + newlen); + if (new != NULL) + { + new[oldlen] = ','; + new[oldlen + 1] = '\0'; + strlcat(*deprecated, + def[n].cd_name, + newlen); + *deprecated = new; + } + } + break; + case CONFIG_TYPE_STRING: case CONFIG_TYPE_INCLUDE: str = p; @@ -359,7 +392,8 @@ config_load_level(char *file, struct configdef *def, return NULL; } - if (def[n].cd_type != CONFIG_TYPE_INCLUDE) + if (def[n].cd_type != CONFIG_TYPE_INCLUDE && + def[n].cd_type != CONFIG_TYPE_DEPRECATED) { new = (struct config *) malloc(sizeof(struct config)); if (new == NULL) @@ -392,7 +426,7 @@ config_load_level(char *file, struct configdef *def, struct config *incl; incl = config_load_level(str, def, line, outpath, - outpathlen, level + 1); + outpathlen, level + 1, deprecated); if (incl == NULL) { if (in != stdin) @@ -420,6 +454,9 @@ config_load_level(char *file, struct configdef *def, new->cfg_int = value; break; + case CONFIG_TYPE_DEPRECATED: + break; + default: assert(0); } @@ -560,11 +597,11 @@ config_free(struct config *head) struct config * config_load(char *file, struct configdef *def, unsigned int *line, - char *path, size_t pathlen) + char *path, size_t pathlen, char **deprecated) { conf_error = CONF_UNKNOWN; - return config_load_level(file, def, line, path, pathlen, 0); + return config_load_level(file, def, line, path, pathlen, 0, deprecated); } /* @@ -721,7 +758,8 @@ config_validname(struct configdef *def, const char *name) if (def[n].cd_name == NULL) return FALSE; - if (strcasecmp(name, def[n].cd_name) == 0) + if (strcasecmp(name, def[n].cd_name) == 0 && + def[n].cd_type != CONFIG_TYPE_DEPRECATED) return TRUE; } diff --git a/opendkim/config.h b/opendkim/config.h index 5eff4928..a5687638 100644 --- a/opendkim/config.h +++ b/opendkim/config.h @@ -2,7 +2,7 @@ ** Copyright (c) 2006-2008 Sendmail, Inc. and its suppliers. ** All rights reserved. ** -** Copyright (c) 2009-2012, The Trusted Domain Project. All rights reserved. +** Copyright (c) 2009-2012, 2015, The Trusted Domain Project. All rights reserved. ** */ @@ -23,6 +23,7 @@ #define CONFIG_TYPE_INTEGER 1 #define CONFIG_TYPE_BOOLEAN 2 #define CONFIG_TYPE_INCLUDE 3 +#define CONFIG_TYPE_DEPRECATED 4 struct config { @@ -48,7 +49,7 @@ extern char *config_error __P((void)); extern void config_free __P((struct config *)); extern int config_get __P((struct config *, const char *, void *, size_t)); extern struct config *config_load __P((char *, struct configdef *, - unsigned int *, char *, size_t)); + unsigned int *, char *, size_t, char **)); extern _Bool config_validname __P((struct configdef *, const char *)); #endif /* _CONFIG_H_ */ diff --git a/opendkim/opendkim-genzone.c b/opendkim/opendkim-genzone.c index 2975a5df..40443436 100644 --- a/opendkim/opendkim-genzone.c +++ b/opendkim/opendkim-genzone.c @@ -401,7 +401,7 @@ main(int argc, char **argv) char path[MAXPATHLEN + 1]; cfg = config_load(configfile, dkimf_config, - &line, path, sizeof path); + &line, path, sizeof path, NULL); if (cfg == NULL) { diff --git a/opendkim/opendkim-spam.c b/opendkim/opendkim-spam.c index 25fa4ffc..61ac4392 100644 --- a/opendkim/opendkim-spam.c +++ b/opendkim/opendkim-spam.c @@ -239,7 +239,7 @@ main(int argc, char **argv) memset(path, '\0', sizeof path); conf = config_load(conffile, spam_config, &line, - path, sizeof path); + path, sizeof path, NULL); if (conf == NULL) { diff --git a/opendkim/opendkim-testkey.c b/opendkim/opendkim-testkey.c index ed59cdef..d8c9f166 100644 --- a/opendkim/opendkim-testkey.c +++ b/opendkim/opendkim-testkey.c @@ -308,7 +308,7 @@ main(int argc, char **argv) char path[MAXPATHLEN + 1]; cfg = config_load(conffile, dkimf_config, &line, - path, sizeof path); + path, sizeof path, NULL); if (cfg == NULL) { diff --git a/opendkim/opendkim.8.in b/opendkim/opendkim.8.in index 6d96249e..c4264702 100644 --- a/opendkim/opendkim.8.in +++ b/opendkim/opendkim.8.in @@ -30,6 +30,7 @@ [\-V] [\-W] [\-x configfile] +[\-X] .SH DESCRIPTION .B opendkim implements the @@ -432,6 +433,17 @@ reload occurs. The OPERATION section describes how reloads are triggered. The default is to read a configuration file from .I @SYSCONFDIR@/opendkim.conf if one exists, or otherwise to apply defaults to all values. +.TP +.I \-X +Tolerates configuration file items that have been internally marked as "deprecated". +Normally when a configuration file item is removed from the package, it is flagged +in this way for at least one full release cycle. The presence of a deprecated +configuration file item typically causes the filter to return an error and refuse to +start. Setting this flag will allow the filter to start and a warning is logged. +In some future release when the item is removed completely, a different error +results, and it will not be possible to start the filter. Use of this flag is +NOT RECOMMENDED; it could effectively hide a major configuration change with serious +security implications. .SH OPERATION A message will be verified unless it conforms to the signing criteria, which are: (1) the domain on the From: address (if present) must be listed diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c index 22219e96..aaf9c5f8 100644 --- a/opendkim/opendkim.c +++ b/opendkim/opendkim.c @@ -136,7 +136,7 @@ #endif /* _FFR_REPUTATION */ /* macros */ -#define CMDLINEOPTS "Ab:c:d:De:fF:k:lL:no:p:P:Qrs:S:t:T:u:vVWx:?" +#define CMDLINEOPTS "Ab:c:d:De:fF:k:lL:no:p:P:Qrs:S:t:T:u:vVWx:X?" #ifndef MIN # define MIN(x,y) ((x) < (y) ? (x) : (y)) @@ -744,6 +744,7 @@ _Bool dolog; /* logging? (exported) */ _Bool reload; /* reload requested */ _Bool no_i_whine; /* noted ${i} is undefined */ _Bool testmode; /* test mode */ +_Bool allowdeprecated; /* allow deprecated config values */ #ifdef QUERY_CACHE _Bool querycache; /* local query cache */ #endif /* QUERY_CACHE */ @@ -6489,24 +6490,9 @@ dkimf_config_load(struct config *data, struct dkimf_config *conf, if (!conf->conf_addswhdr) { - (void) config_get(data, "X-Header", + (void) config_get(data, "SoftwareHeader", &conf->conf_addswhdr, sizeof conf->conf_addswhdr); - - if (conf->conf_addswhdr) - { - if (conf->conf_dolog) - { - syslog(LOG_WARNING, - "\"X-Header\" deprecated; use \"SoftwareHeader\" instead"); - } - } - else - { - (void) config_get(data, "SoftwareHeader", - &conf->conf_addswhdr, - sizeof conf->conf_addswhdr); - } } (void) config_get(data, "DomainKeysCompat", @@ -8795,12 +8781,13 @@ dkimf_config_reload(void) struct config *cfg; char *missing; char *errstr = NULL; + char *deprecated = NULL; char path[MAXPATHLEN + 1]; strlcpy(path, conffile, sizeof path); cfg = config_load(conffile, dkimf_config, &line, - path, sizeof path); + path, sizeof path, &deprecated); if (cfg == NULL) { @@ -8814,6 +8801,26 @@ dkimf_config_reload(void) err = TRUE; } + if (deprecated != NULL) + { + char *action = "aborting"; + if (allowdeprecated) + action = "continuing"; + + if (curconf->conf_dolog) + { + syslog(LOG_WARNING, + "%s: settings found for deprecated value(s): %s; %s", + path, deprecated, action); + } + + if (!allowdeprecated) + { + dkimf_config_free(new); + err = TRUE; + } + } + if (!err) { missing = config_check(cfg, dkimf_config); @@ -15551,6 +15558,10 @@ main(int argc, char **argv) conffile = optarg; break; + case 'X': + allowdeprecated = TRUE; + break; + default: return usage(); } @@ -15592,10 +15603,11 @@ main(int argc, char **argv) { u_int line = 0; char *missing; + char *deprecated = NULL; char path[MAXPATHLEN + 1]; cfg = config_load(conffile, dkimf_config, - &line, path, sizeof path); + &line, path, sizeof path, &deprecated); if (cfg == NULL) { @@ -15621,6 +15633,24 @@ main(int argc, char **argv) dkimf_config_free(curconf); return EX_CONFIG; } + + if (deprecated != NULL) + { + char *action = "aborting"; + if (allowdeprecated) + action = "continuing"; + + fprintf(stderr, + "%s: %s: settings found for deprecated value(s): %s; %s\n", + progname, conffile, deprecated, action); + + if (!allowdeprecated) + { + config_free(cfg); + dkimf_config_free(curconf); + return EX_CONFIG; + } + } } if (dkimf_config_load(cfg, curconf, err, sizeof err, become) != 0)