dovecot-2.2: doveconf: Added -H parameter to check for hostname ...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Feb 18 08:46:15 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/62a930eb22b5
changeset: 15831:62a930eb22b5
user: Timo Sirainen <tss at iki.fi>
date: Mon Feb 18 08:46:06 2013 +0200
description:
doveconf: Added -H parameter to check for hostname hash duplicates.
diffstat:
src/config/doveconf.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 116 insertions(+), 2 deletions(-)
diffs (170 lines):
diff -r 80344aedd8fd -r 62a930eb22b5 src/config/doveconf.c
--- a/src/config/doveconf.c Mon Feb 18 08:45:54 2013 +0200
+++ b/src/config/doveconf.c Mon Feb 18 08:46:06 2013 +0200
@@ -5,6 +5,9 @@
#include "abspath.h"
#include "module-dir.h"
#include "env-util.h"
+#include "guid.h"
+#include "hash.h"
+#include "hostpid.h"
#include "ostream.h"
#include "str.h"
#include "strescape.h"
@@ -19,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#include <unistd.h>
#include <sysexits.h>
@@ -564,6 +568,110 @@
}
}
+struct hostname_format {
+ const char *prefix, *suffix;
+ unsigned int numcount;
+ bool zeropadding;
+};
+
+static void
+hostname_format_write(string_t *str, const struct hostname_format *fmt,
+ unsigned int num)
+{
+ str_truncate(str, 0);
+ str_append(str, fmt->prefix);
+ if (!fmt->zeropadding)
+ str_printfa(str, "%d", num);
+ else
+ str_printfa(str, "%0*d", fmt->numcount, num);
+ str_append(str, fmt->suffix);
+}
+
+static void hostname_verify_format(const char *arg)
+{
+ struct hostname_format fmt;
+ const char *p;
+ unsigned char hash[GUID_128_HOST_HASH_SIZE];
+ unsigned int len, n, limit;
+ HASH_TABLE(void *, void *) hosts;
+ void *key, *value;
+ string_t *host;
+ const char *host2;
+ bool duplicates = FALSE;
+
+ memset(&fmt, 0, sizeof(fmt));
+ if (arg != NULL) {
+ /* host%d, host%2d, host%02d */
+ p = strchr(arg, '%');
+ if (p == NULL)
+ i_fatal("Host parameter missing %%d");
+ fmt.prefix = t_strdup_until(arg, p++);
+ if (*p == '0') {
+ fmt.zeropadding = TRUE;
+ p++;
+ }
+ if (!i_isdigit(*p))
+ fmt.numcount = 1;
+ else
+ fmt.numcount = *p++ - '0';
+ if (*p++ != 'd')
+ i_fatal("Host parameter missing %%d");
+ fmt.suffix = p;
+ } else {
+ /* detect host1[suffix] vs host01[suffix] */
+ len = strlen(my_hostname);
+ while (len > 0 && !i_isdigit(my_hostname[len-1]))
+ len--;
+ fmt.suffix = my_hostname + len;
+ fmt.numcount = 0;
+ while (len > 0 && i_isdigit(my_hostname[len-1])) {
+ len--;
+ fmt.numcount++;
+ }
+ if (my_hostname[len] == '0')
+ fmt.zeropadding = TRUE;
+ fmt.prefix = t_strndup(my_hostname, len);
+ if (fmt.numcount == 0) {
+ i_fatal("Hostname '%s' has no digits, can't verify",
+ my_hostname);
+ }
+ }
+ for (n = 0, limit = 1; n < fmt.numcount; n++)
+ limit *= 10;
+ host = t_str_new(128);
+ hash_table_create_direct(&hosts, default_pool, limit);
+ for (n = 0; n < limit; n++) {
+ hostname_format_write(host, &fmt, n);
+
+ guid_128_host_hash_get(str_c(host), hash);
+ i_assert(sizeof(key) >= sizeof(hash));
+ key = NULL; memcpy(&key, hash, sizeof(hash));
+
+ value = hash_table_lookup(hosts, key);
+ if (value != NULL) {
+ host2 = t_strdup(str_c(host));
+ hostname_format_write(host, &fmt,
+ POINTER_CAST_TO(value, unsigned int)-1);
+ i_error("Duplicate host hashes: %s and %s",
+ str_c(host), host2);
+ duplicates = TRUE;
+ } else {
+ hash_table_insert(hosts, key, POINTER_CAST(n+1));
+ }
+ }
+ hash_table_destroy(&hosts);
+
+ if (duplicates)
+ exit(EX_CONFIG);
+ else {
+ host2 = t_strdup(str_c(host));
+ hostname_format_write(host, &fmt, 0);
+ printf("No duplicate host hashes in %s .. %s\n",
+ str_c(host), host2);
+ exit(0);
+ }
+}
+
static void check_wrong_config(const char *config_path)
{
const char *base_dir, *symlink_path, *prev_path;
@@ -598,7 +706,7 @@
int c, ret, ret2;
bool config_path_specified, expand_vars = FALSE, hide_key = FALSE;
bool parse_full_config = FALSE, simple_output = FALSE;
- bool dump_defaults = FALSE;
+ bool dump_defaults = FALSE, host_verify = FALSE;
if (getenv("USE_SYSEXITS") != NULL) {
/* we're coming from (e.g.) LDA */
@@ -608,7 +716,7 @@
memset(&filter, 0, sizeof(filter));
master_service = master_service_init("config",
MASTER_SERVICE_FLAG_STANDALONE,
- &argc, &argv, "adf:hm:nNpexS");
+ &argc, &argv, "adf:hHm:nNpexS");
orig_config_path = master_service_get_config_path(master_service);
i_set_failure_prefix("doveconf: ");
@@ -630,6 +738,9 @@
case 'h':
hide_key = TRUE;
break;
+ case 'H':
+ host_verify = TRUE;
+ break;
case 'm':
module = t_strdup(optarg);
array_append(&module_names, &module, 1);
@@ -662,6 +773,9 @@
-c parameter */
config_path_specified = strcmp(config_path, orig_config_path) != 0;
+ if (host_verify)
+ hostname_verify_format(argv[optind]);
+
if (c == 'e') {
if (argv[optind] == NULL)
i_fatal("Missing command for -e");
More information about the dovecot-cvs
mailing list