diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2010-02-17 13:47:32 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2010-02-17 13:47:32 +0000 |
commit | 316ac1abd4f2cabe81f2fc2ffdb214a73e2826c7 (patch) | |
tree | 923ab1056190015c67e286f489735aa375dc3ce7 | |
parent | bcf59d155fc077e59ed56c56c8edf5b332633995 (diff) |
the map api becomes backend-agnostic with initial support for db(3) and
stdio(3) backends, though for now we only enable db(3). this is the first
commit of a serie to improve maps and everything related.
idea discussed with and diff okay jacekm@
-rw-r--r-- | usr.sbin/smtpd/lka.c | 15 | ||||
-rw-r--r-- | usr.sbin/smtpd/map.c | 184 | ||||
-rw-r--r-- | usr.sbin/smtpd/ruleset.c | 4 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 5 |
4 files changed, 164 insertions, 44 deletions
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c index acd77505125..ce3bc2944f8 100644 --- a/usr.sbin/smtpd/lka.c +++ b/usr.sbin/smtpd/lka.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lka.c,v 1.99 2010/02/17 08:40:24 gilles Exp $ */ +/* $OpenBSD: lka.c,v 1.100 2010/02/17 13:47:31 gilles Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -416,11 +416,16 @@ lka_dispatch_mta(int sig, short event, void *p) case IMSG_LKA_SECRET: { struct secret *query = imsg.data; char *secret = NULL; - char *map = "secrets"; + struct map *map = NULL; + char *mapname = "secrets"; IMSG_SIZE_CHECK(query); - secret = map_dblookupbyname(env, map, query->host); + /* should not happen */ + map = map_findbyname(env, mapname); + if (map == NULL) + fatalx("secrets map has disappeared"); + secret = map_lookup(env, map->m_id, query->host); log_debug("secret for %s %s", query->host, secret ? "found" : "not found"); @@ -429,11 +434,11 @@ lka_dispatch_mta(int sig, short event, void *p) if (secret == NULL) { log_warnx("failed to lookup %s in the %s map", - query->host, map); + query->host, mapname); } else if (! lka_encode_credentials(query->secret, sizeof(query->secret), secret)) { log_warnx("parse error for %s in the %s map", - query->host, map); + query->host, mapname); } imsg_compose_event(iev, IMSG_LKA_SECRET, 0, 0, -1, query, diff --git a/usr.sbin/smtpd/map.c b/usr.sbin/smtpd/map.c index f3b5547246c..3d0f301a266 100644 --- a/usr.sbin/smtpd/map.c +++ b/usr.sbin/smtpd/map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: map.c,v 1.7 2009/11/03 22:57:41 gilles Exp $ */ +/* $OpenBSD: map.c,v 1.8 2010/02/17 13:47:31 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -22,7 +22,9 @@ #include <sys/param.h> #include <sys/socket.h> +#include <ctype.h> #include <db.h> +#include <err.h> #include <errno.h> #include <event.h> #include <fcntl.h> @@ -32,6 +34,32 @@ #include "smtpd.h" +/* db(3) backend */ +void *map_db_open(char *); +void map_db_close(void *); +char *map_db_get(void *, char *); +int map_db_put(void *, char *, char *); + +/* stdio(3) backend */ +void *map_stdio_open(char *); +void map_stdio_close(void *); +char *map_stdio_get(void *, char *); +int map_stdio_put(void *, char *, char *); + + +struct map_backend { + enum map_src map_type; + void *(*open)(char *); + void (*close)(void *); + char *(*get)(void *, char *); + int (*put)(void *, char *, char *); +} map_backends[] = { + { S_DB, + map_db_open, map_db_close, map_db_get, map_db_put }, + { S_FILE, + map_stdio_open, map_stdio_close, map_stdio_get, map_stdio_put }, +}; + struct map * map_findbyname(struct smtpd *env, const char *name) { @@ -57,59 +85,147 @@ map_find(struct smtpd *env, objid_t id) } char * -map_dblookup(struct smtpd *env, objid_t mapid, char *keyname) +map_lookup(struct smtpd *env, objid_t mapid, char *key) { - int ret; - DBT key; - DBT val; - DB *db; - struct map *map; + u_int8_t i; + void *hdl = NULL; char *result = NULL; + struct map *map; + struct map_backend *backend = NULL; map = map_find(env, mapid); if (map == NULL) return NULL; - if (map->m_src != S_DB) { - log_warn("invalid map type for map %d", map->m_id); - return NULL; - } + for (i = 0; i < nitems(map_backends); ++i) + if (map_backends[i].map_type == map->m_src) + break; + + if (i == nitems(map_backends)) + fatalx("invalid map type"); - db = dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL); - if (db == NULL) { - log_warn("map_dblookup: can't open %s", map->m_config); + backend = &map_backends[i]; + hdl = backend->open(map->m_config); + if (hdl == NULL) { + log_warn("map_lookup: can't open %s", map->m_config); return NULL; } - key.data = keyname; - key.size = strlen(key.data) + 1; + result = backend->get(hdl, key); + backend->close(hdl); - if ((ret = db->get(db, &key, &val, 0)) == -1) { - log_warn("map_dblookup: map '%d'", map->m_id); - db->close(db); - return NULL; - } + return result; +} - if (ret == 0) { - result = calloc(val.size, 1); - if (result == NULL) - fatal("calloc"); - (void)strlcpy(result, val.data, val.size); - } - db->close(db); +/* db(3) backend */ +void * +map_db_open(char *src) +{ + return dbopen(src, O_RDONLY, 0600, DB_HASH, NULL); +} + +void +map_db_close(void *hdl) +{ + DB *db = hdl; - return ret == 0 ? result : NULL; + db->close(db); } char * -map_dblookupbyname(struct smtpd *env, char *mapname, char *keyname) +map_db_get(void *hdl, char *key) { - struct map *map; + int ret; + DBT dbk; + DBT dbv; + DB *db = hdl; + char *result = NULL; - map = map_findbyname(env, mapname); - if (map == NULL) + dbk.data = key; + dbk.size = strlen(dbk.data) + 1; + + if ((ret = db->get(db, &dbk, &dbv, 0)) != 0) return NULL; - return map_dblookup(env, map->m_id, keyname); + result = calloc(dbv.size, 1); + if (result == NULL) + fatal("calloc"); + (void)strlcpy(result, dbv.data, dbv.size); + + return result; +} + +int +map_db_put(void *hdl, char *key, char *val) +{ + return 0; +} + + +/* stdio(3) backend */ +void * +map_stdio_open(char *src) +{ + return fopen(src, "r"); +} + +void +map_stdio_close(void *hdl) +{ + FILE *fp = hdl; + + fclose(fp); +} + +char * +map_stdio_get(void *hdl, char *key) +{ + char *buf, *lbuf; + size_t len; + char *keyp; + char *valp; + FILE *fp = hdl; + char *result = NULL; + + lbuf = NULL; + while ((buf = fgetln(fp, &len))) { + if (buf[len - 1] == '\n') + buf[len - 1] = '\0'; + else { + if ((lbuf = malloc(len + 1)) == NULL) + err(1, NULL); + memcpy(lbuf, buf, len); + lbuf[len] = '\0'; + buf = lbuf; + } + + keyp = buf; + while (isspace((int)*keyp)) + ++keyp; + if (*keyp == '\0' || *keyp == '#') + continue; + + valp = keyp; + strsep(&valp, " \t:"); + if (valp == NULL || valp == keyp) + continue; + + if (strcmp(keyp, key) != 0) + continue; + + result = strdup(lbuf); + if (result == NULL) + err(1, NULL); + break; + } + free(lbuf); + + return result; +} + +int +map_stdio_put(void *hdl, char *key, char *val) +{ + return 0; } diff --git a/usr.sbin/smtpd/ruleset.c b/usr.sbin/smtpd/ruleset.c index acfb6214f1b..47df11070cd 100644 --- a/usr.sbin/smtpd/ruleset.c +++ b/usr.sbin/smtpd/ruleset.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ruleset.c,v 1.8 2009/11/03 22:57:41 gilles Exp $ */ +/* $OpenBSD: ruleset.c,v 1.9 2010/02/17 13:47:31 gilles Exp $ */ /* * Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org> @@ -79,7 +79,7 @@ ruleset_match(struct smtpd *env, char *tag, struct path *path, struct sockaddr_s } break; case S_DB: - if (map_dblookup(env, map->m_id, path->domain) != NULL) { + if (map_lookup(env, map->m_id, path->domain) != NULL) { path->cond = cond; return r; } diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 7e7c4fee1e9..ab75dd46fb4 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.168 2010/01/10 16:42:35 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.169 2010/02/17 13:47:31 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -929,8 +929,7 @@ void show_queue(char *, int); u_int16_t queue_hash(char *); /* map.c */ -char *map_dblookup(struct smtpd *, objid_t, char *); -char *map_dblookupbyname(struct smtpd *, char *, char *); +char *map_lookup(struct smtpd *, objid_t, char *); /* mda.c */ pid_t mda(struct smtpd *); |