summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2010-02-17 13:47:32 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2010-02-17 13:47:32 +0000
commit316ac1abd4f2cabe81f2fc2ffdb214a73e2826c7 (patch)
tree923ab1056190015c67e286f489735aa375dc3ce7
parentbcf59d155fc077e59ed56c56c8edf5b332633995 (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.c15
-rw-r--r--usr.sbin/smtpd/map.c184
-rw-r--r--usr.sbin/smtpd/ruleset.c4
-rw-r--r--usr.sbin/smtpd/smtpd.h5
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 *);