summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2010-04-27 09:49:24 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2010-04-27 09:49:24 +0000
commitc5e412cc3c0ed99c754af772a1680a199acf72ab (patch)
tree9caebb17c70842a04fd146808e1bee7589b8fceb
parent7e32eeaab109e135c198149e47b67e1d07f69691 (diff)
initial work at fixing aliases support:
- kill struct alias, struct expandnode is used instead - introduce map_parse_alias() and map_parse_virtual() - aliases and virtual code no longer assume db(3) but use the map API which lets them become backend agnostic AND value-checked. this actually makes the code simpler by removing all values parsing from aliases.c - rename K_SECRETS -> K_SECRET, K_ALIASES -> K_ALIAS for consistency the enum has singular names. - aliases, virtual and forward now work with an expandtree and deal with multiple levels of resolving by merging expandtree's more coming soon ;)
-rw-r--r--usr.sbin/smtpd/aliases.c316
-rw-r--r--usr.sbin/smtpd/expand.c39
-rw-r--r--usr.sbin/smtpd/forward.c12
-rw-r--r--usr.sbin/smtpd/lka.c12
-rw-r--r--usr.sbin/smtpd/makemap.c38
-rw-r--r--usr.sbin/smtpd/map.c4
-rw-r--r--usr.sbin/smtpd/map_parser.c102
-rw-r--r--usr.sbin/smtpd/smtpd.h58
8 files changed, 282 insertions, 299 deletions
diff --git a/usr.sbin/smtpd/aliases.c b/usr.sbin/smtpd/aliases.c
index c0b2fcb0c31..4ee42e8a1f9 100644
--- a/usr.sbin/smtpd/aliases.c
+++ b/usr.sbin/smtpd/aliases.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aliases.c,v 1.31 2009/11/09 23:54:08 gilles Exp $ */
+/* $OpenBSD: aliases.c,v 1.32 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -35,275 +35,175 @@
#include "smtpd.h"
int aliases_expand_include(struct expandtree *, char *);
-int alias_is_filter(struct alias *, char *, size_t);
-int alias_is_username(struct alias *, char *, size_t);
-int alias_is_address(struct alias *, char *, size_t);
-int alias_is_filename(struct alias *, char *, size_t);
-int alias_is_include(struct alias *, char *, size_t);
+int alias_is_filter(struct expandnode *, char *, size_t);
+int alias_is_username(struct expandnode *, char *, size_t);
+int alias_is_address(struct expandnode *, char *, size_t);
+int alias_is_filename(struct expandnode *, char *, size_t);
+int alias_is_include(struct expandnode *, char *, size_t);
int
aliases_exist(struct smtpd *env, objid_t mapid, char *username)
{
- char buf[MAXLOGNAME];
- int ret;
- DBT key;
- DBT val;
- DB *aliasesdb;
struct map *map;
+ struct map_alias *map_alias;
+ char buf[MAXLOGNAME];
map = map_find(env, mapid);
if (map == NULL)
return 0;
- aliasesdb = dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL);
- if (aliasesdb == NULL) {
- log_warn("aliases_exist: dbopen: %s", map->m_config);
- return 0;
- }
-
lowercase(buf, username, sizeof(buf));
+ map_alias = map_lookup(env, mapid, buf, K_ALIAS);
+ if (map_alias == NULL)
+ return 0;
- key.data = buf;
- key.size = strlen(key.data) + 1;
+ /* XXX - for now the map API always allocate */
+ log_debug("aliases_exist: '%s' exists with %zd expansion nodes",
+ username, map_alias->nbnodes);
- ret = aliasesdb->get(aliasesdb, &key, &val, 0);
- if (ret == -1)
- log_warn("aliases_exist");
- aliasesdb->close(aliasesdb);
+ expandtree_free_nodes(&map_alias->expandtree);
+ free(map_alias);
- return (ret == 0);
+ return 1;
}
int
aliases_get(struct smtpd *env, objid_t mapid, struct expandtree *expandtree, char *username)
{
- char buf[MAXLOGNAME];
- int ret;
- DBT key;
- DBT val;
- DB *aliasesdb;
- size_t nbaliases, nbsave;
- struct alias alias;
- struct alias *nextalias;
struct map *map;
- struct expand_node expnode;
+ struct map_alias *map_alias;
+ struct expandnode *expnode;
+ char buf[MAXLOGNAME];
+ size_t nbaliases;
map = map_find(env, mapid);
if (map == NULL)
return 0;
- aliasesdb = dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL);
- if (aliasesdb == NULL) {
- log_warn("aliases_get: dbopen: %s", map->m_config);
- return 0;
- }
-
lowercase(buf, username, sizeof(buf));
-
- key.data = buf;
- key.size = strlen(key.data) + 1;
-
- if ((ret = aliasesdb->get(aliasesdb, &key, &val, 0)) != 0) {
- if (ret == -1)
- log_warn("aliases_get");
- aliasesdb->close(aliasesdb);
- return 0;
- }
-
- nbsave = nbaliases = val.size / sizeof(struct alias);
- if (nbaliases == 0) {
- aliasesdb->close(aliasesdb);
+ map_alias = map_lookup(env, mapid, buf, K_ALIAS);
+ if (map_alias == NULL)
return 0;
- }
- nextalias = (struct alias *)val.data;
- do {
- alias = *nextalias;
- ++nextalias;
- if (alias.type == EXPAND_INCLUDE) {
- aliases_expand_include(expandtree, alias.u.filename);
- }
+ /* foreach node in map_alias expandtree, we merge */
+ nbaliases = 0;
+ RB_FOREACH(expnode, expandtree, &map_alias->expandtree) {
+ if (expnode->type == EXPAND_INCLUDE)
+ nbaliases += aliases_expand_include(expandtree, expnode->u.filename);
else {
- bzero(&expnode, sizeof(struct expand_node));
- alias_to_expand_node(&expnode, &alias);
- expandtree_increment_node(expandtree, &expnode);
+ expandtree_increment_node(expandtree, expnode);
+ nbaliases++;
}
- } while (--nbaliases);
- aliasesdb->close(aliasesdb);
- return nbsave;
+ }
+
+ expandtree_free_nodes(&map_alias->expandtree);
+ free(map_alias);
+
+ log_debug("aliases_get: returned %zd aliases", nbaliases);
+ return nbaliases;
}
int
aliases_vdomain_exists(struct smtpd *env, objid_t mapid, char *hostname)
{
- int ret;
- DBT key;
- DBT val;
- DB *vtable;
struct map *map;
- char strkey[MAX_LINE_SIZE];
+ struct map_virtual *map_virtual;
+ char buf[MAXHOSTNAMELEN];
map = map_find(env, mapid);
if (map == NULL)
return 0;
- vtable = dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL);
- if (vtable == NULL) {
- log_warn("aliases_vdomain_exists: dbopen: %s", map->m_config);
+ lowercase(buf, hostname, sizeof(buf));
+ map_virtual = map_lookup(env, mapid, buf, K_VIRTUAL);
+ if (map_virtual == NULL)
return 0;
- }
- if (! bsnprintf(strkey, sizeof(strkey), "%s", hostname)) {
- vtable->close(vtable);
- return 0;
- }
- lowercase(strkey, strkey, sizeof(strkey));
+ /* XXX - for now the map API always allocate */
+ log_debug("aliases_vdomain_exist: '%s' exists", hostname);
+ expandtree_free_nodes(&map_virtual->expandtree);
+ free(map_virtual);
- key.data = strkey;
- key.size = strlen(key.data) + 1;
- ret = vtable->get(vtable, &key, &val, 0);
- if (ret == -1)
- log_warn("aliases_vdomain_exists");
-
- vtable->close(vtable);
-
- return (ret == 0);
+ return 1;
}
int
aliases_virtual_exist(struct smtpd *env, objid_t mapid, struct path *path)
{
- int ret;
- DBT key;
- DBT val;
- DB *aliasesdb;
struct map *map;
- char strkey[MAX_LINE_SIZE];
+ struct map_virtual *map_virtual;
+ char buf[MAX_LINE_SIZE];
+ char *pbuf = buf;
map = map_find(env, mapid);
if (map == NULL)
return 0;
- aliasesdb = dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL);
- if (aliasesdb == NULL) {
- log_warn("aliases_virtual_exist: dbopen: %s", map->m_config);
+ if (! bsnprintf(buf, sizeof(buf), "%s@%s", path->user,
+ path->domain))
return 0;
- }
+ lowercase(buf, buf, sizeof(buf));
- if (! bsnprintf(strkey, sizeof(strkey), "%s@%s", path->user,
- path->domain)) {
- aliasesdb->close(aliasesdb);
- return 0;
+ map_virtual = map_lookup(env, mapid, buf, K_VIRTUAL);
+ if (map_virtual == NULL) {
+ pbuf = strchr(buf, '@');
+ map_virtual = map_lookup(env, mapid, pbuf, K_VIRTUAL);
}
+ if (map_virtual == NULL)
+ return 0;
- lowercase(strkey, strkey, sizeof(strkey));
-
- key.data = strkey;
- key.size = strlen(key.data) + 1;
-
- if ((ret = aliasesdb->get(aliasesdb, &key, &val, 0)) != 0) {
- if (ret == -1)
- log_warn("aliases_virtual_exist");
-
- if (! bsnprintf(strkey, sizeof(strkey), "@%s", path->domain)) {
- aliasesdb->close(aliasesdb);
- return 0;
- }
-
- lowercase(strkey, strkey, sizeof(strkey));
-
- key.data = strkey;
- key.size = strlen(key.data) + 1;
-
- ret = aliasesdb->get(aliasesdb, &key, &val, 0);
- }
- if (ret == -1)
- log_warn("aliases_virtual_exist");
- aliasesdb->close(aliasesdb);
+ log_debug("aliases_virtual_exist: '%s' exists", pbuf);
+ expandtree_free_nodes(&map_virtual->expandtree);
+ free(map_virtual);
- return (ret == 0);
+ return 1;
}
int
aliases_virtual_get(struct smtpd *env, objid_t mapid,
struct expandtree *expandtree, struct path *path)
{
- int ret;
- DBT key;
- DBT val;
- DB *aliasesdb;
- size_t nbaliases, nbsave;
- struct alias alias;
- struct alias *nextalias;
struct map *map;
- char strkey[MAX_LINE_SIZE];
- struct expand_node expnode;
+ struct map_virtual *map_virtual;
+ struct expandnode *expnode;
+ char buf[MAX_LINE_SIZE];
+ char *pbuf = buf;
+ int nbaliases;
map = map_find(env, mapid);
if (map == NULL)
return 0;
- aliasesdb = dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL);
- if (aliasesdb == NULL) {
- log_warn("aliases_virtual_get: dbopen: %s", map->m_config);
+ if (! bsnprintf(buf, sizeof(buf), "%s@%s", path->user,
+ path->domain))
return 0;
- }
+ lowercase(buf, buf, sizeof(buf));
- if (! bsnprintf(strkey, sizeof(strkey), "%s@%s", path->user,
- path->domain)) {
- aliasesdb->close(aliasesdb);
- return 0;
+ map_virtual = map_lookup(env, mapid, buf, K_VIRTUAL);
+ if (map_virtual == NULL) {
+ pbuf = strchr(buf, '@');
+ map_virtual = map_lookup(env, mapid, pbuf, K_VIRTUAL);
}
+ if (map_virtual == NULL)
+ return 0;
- lowercase(strkey, strkey, sizeof(strkey));
-
- key.data = strkey;
- key.size = strlen(key.data) + 1;
-
- if ((ret = aliasesdb->get(aliasesdb, &key, &val, 0)) != 0) {
- if (ret == -1)
- log_warn("aliases_virtual_get");
-
- if (! bsnprintf(strkey, sizeof(strkey), "@%s", path->domain)) {
- aliasesdb->close(aliasesdb);
- return 0;
- }
-
- lowercase(strkey, strkey, sizeof(strkey));
-
- key.data = strkey;
- key.size = strlen(key.data) + 1;
-
- if ((ret = aliasesdb->get(aliasesdb, &key, &val, 0)) != 0) {
- if (ret == -1)
- log_warn("aliases_virtual_get");
- aliasesdb->close(aliasesdb);
- return 0;
+ /* foreach node in map_virtual expandtree, we merge */
+ nbaliases = 0;
+ RB_FOREACH(expnode, expandtree, &map_virtual->expandtree) {
+ if (expnode->type == EXPAND_INCLUDE)
+ nbaliases += aliases_expand_include(expandtree, expnode->u.filename);
+ else {
+ expandtree_increment_node(expandtree, expnode);
+ nbaliases++;
}
}
- nbsave = nbaliases = val.size / sizeof(struct alias);
- if (nbaliases == 0) {
- aliasesdb->close(aliasesdb);
- return 0;
- }
+ expandtree_free_nodes(&map_virtual->expandtree);
+ free(map_virtual);
+ log_debug("aliases_virtual_get: '%s' resolved to %d nodes", pbuf, nbaliases);
- nextalias = (struct alias *)val.data;
- do {
- alias = *nextalias;
- ++nextalias;
- if (alias.type == EXPAND_INCLUDE) {
- aliases_expand_include(expandtree, alias.u.filename);
- }
- else {
- bzero(&expnode, sizeof(struct expand_node));
- alias_to_expand_node(&expnode, &alias);
- expandtree_increment_node(expandtree, &expnode);
- }
- } while (--nbaliases);
- aliasesdb->close(aliasesdb);
- return nbsave;
+ return nbaliases;
}
int
@@ -314,8 +214,7 @@ aliases_expand_include(struct expandtree *expandtree, char *filename)
size_t len;
size_t lineno = 0;
char delim[] = { '\\', '#' };
- struct alias alias;
- struct expand_node expnode;
+ struct expandnode expnode;
fp = fopen(filename, "r");
if (fp == NULL) {
@@ -328,18 +227,16 @@ aliases_expand_include(struct expandtree *expandtree, char *filename)
free(line);
continue;
}
- if (! alias_parse(&alias, line)) {
+
+ bzero(&expnode, sizeof(struct expandnode));
+ if (! alias_parse(&expnode, line)) {
log_warnx("could not parse include entry \"%s\".", line);
}
- if (alias.type == EXPAND_INCLUDE) {
+ if (expnode.type == EXPAND_INCLUDE)
log_warnx("nested inclusion is not supported.");
- }
- else {
- bzero(&expnode, sizeof(struct expand_node));
- alias_to_expand_node(&expnode, &alias);
+ else
expandtree_increment_node(expandtree, &expnode);
- }
free(line);
}
@@ -349,10 +246,10 @@ aliases_expand_include(struct expandtree *expandtree, char *filename)
}
int
-alias_parse(struct alias *alias, char *line)
+alias_parse(struct expandnode *alias, char *line)
{
size_t i;
- int (*f[])(struct alias *, char *, size_t) = {
+ int (*f[])(struct expandnode *, char *, size_t) = {
alias_is_include,
alias_is_filter,
alias_is_filename,
@@ -370,7 +267,7 @@ alias_parse(struct alias *alias, char *line)
}
for (i = 0; i < sizeof(f) / sizeof(void *); ++i) {
- bzero(alias, sizeof(struct alias));
+ bzero(alias, sizeof(struct expandnode));
if (f[i](alias, line, strlen(line)))
break;
}
@@ -382,7 +279,7 @@ alias_parse(struct alias *alias, char *line)
int
-alias_is_filter(struct alias *alias, char *line, size_t len)
+alias_is_filter(struct expandnode *alias, char *line, size_t len)
{
if (strncmp(line, "\"|", 2) == 0 &&
line[len - 1] == '"') {
@@ -396,7 +293,7 @@ alias_is_filter(struct alias *alias, char *line, size_t len)
}
int
-alias_is_username(struct alias *alias, char *line, size_t len)
+alias_is_username(struct expandnode *alias, char *line, size_t len)
{
if (strlcpy(alias->u.username, line,
sizeof(alias->u.username)) >= sizeof(alias->u.username))
@@ -414,7 +311,7 @@ alias_is_username(struct alias *alias, char *line, size_t len)
}
int
-alias_is_address(struct alias *alias, char *line, size_t len)
+alias_is_address(struct expandnode *alias, char *line, size_t len)
{
char *domain;
@@ -455,7 +352,7 @@ alias_is_address(struct alias *alias, char *line, size_t len)
}
int
-alias_is_filename(struct alias *alias, char *line, size_t len)
+alias_is_filename(struct expandnode *alias, char *line, size_t len)
{
if (*line != '/')
return 0;
@@ -468,7 +365,7 @@ alias_is_filename(struct alias *alias, char *line, size_t len)
}
int
-alias_is_include(struct alias *alias, char *line, size_t len)
+alias_is_include(struct expandnode *alias, char *line, size_t len)
{
if (strncasecmp(":include:", line, 9) != 0)
return 0;
@@ -479,10 +376,3 @@ alias_is_include(struct alias *alias, char *line, size_t len)
alias->type = EXPAND_INCLUDE;
return 1;
}
-
-void
-alias_to_expand_node(struct expand_node *expnode, struct alias *alias)
-{
- expnode->type = alias->type;
- expnode->u = alias->u;
-}
diff --git a/usr.sbin/smtpd/expand.c b/usr.sbin/smtpd/expand.c
index 5786937018c..b3fbcdf54dd 100644
--- a/usr.sbin/smtpd/expand.c
+++ b/usr.sbin/smtpd/expand.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: expand.c,v 1.3 2009/11/09 23:49:34 gilles Exp $ */
+/* $OpenBSD: expand.c,v 1.4 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org>
@@ -33,23 +33,23 @@
#include "smtpd.h"
-struct expand_node *
-expandtree_lookup(struct expandtree *expandtree, struct expand_node *node)
+struct expandnode *
+expandtree_lookup(struct expandtree *expandtree, struct expandnode *node)
{
- struct expand_node key;
+ struct expandnode key;
key = *node;
return RB_FIND(expandtree, expandtree, &key);
}
void
-expandtree_increment_node(struct expandtree *expandtree, struct expand_node *node)
+expandtree_increment_node(struct expandtree *expandtree, struct expandnode *node)
{
- struct expand_node *p;
+ struct expandnode *p;
p = expandtree_lookup(expandtree, node);
if (p == NULL) {
- p = calloc(1, sizeof(struct expand_node));
+ p = calloc(1, sizeof(struct expandnode));
if (p == NULL)
fatal("calloc");
*p = *node;
@@ -60,9 +60,9 @@ expandtree_increment_node(struct expandtree *expandtree, struct expand_node *nod
}
void
-expandtree_decrement_node(struct expandtree *expandtree, struct expand_node *node)
+expandtree_decrement_node(struct expandtree *expandtree, struct expandnode *node)
{
- struct expand_node *p;
+ struct expandnode *p;
p = expandtree_lookup(expandtree, node);
if (p == NULL)
@@ -72,9 +72,9 @@ expandtree_decrement_node(struct expandtree *expandtree, struct expand_node *nod
}
void
-expandtree_remove_node(struct expandtree *expandtree, struct expand_node *node)
+expandtree_remove_node(struct expandtree *expandtree, struct expandnode *node)
{
- struct expand_node *p;
+ struct expandnode *p;
p = expandtree_lookup(expandtree, node);
if (p == NULL)
@@ -83,8 +83,21 @@ expandtree_remove_node(struct expandtree *expandtree, struct expand_node *node)
RB_REMOVE(expandtree, expandtree, p);
}
+void
+expandtree_free_nodes(struct expandtree *expandtree)
+{
+ struct expandnode *p;
+ struct expandnode *nxt;
+
+ for (p = RB_MIN(expandtree, expandtree); p != NULL; p = nxt) {
+ nxt = RB_NEXT(expandtree, expandtree, p);
+ RB_REMOVE(expandtree, expandtree, p);
+ free(p);
+ }
+}
+
int
-expand_cmp(struct expand_node *e1, struct expand_node *e2)
+expand_cmp(struct expandnode *e1, struct expandnode *e2)
{
if (e1->type < e2->type)
return -1;
@@ -95,4 +108,4 @@ expand_cmp(struct expand_node *e1, struct expand_node *e2)
return memcmp(&e1->u, &e2->u, sizeof(e1->u));
}
-RB_GENERATE(expandtree, expand_node, entry, expand_cmp);
+RB_GENERATE(expandtree, expandnode, entry, expand_cmp);
diff --git a/usr.sbin/smtpd/forward.c b/usr.sbin/smtpd/forward.c
index f94a6921340..cc34ab08f14 100644
--- a/usr.sbin/smtpd/forward.c
+++ b/usr.sbin/smtpd/forward.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: forward.c,v 1.20 2009/11/09 23:54:08 gilles Exp $ */
+/* $OpenBSD: forward.c,v 1.21 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -38,12 +38,11 @@ int
forwards_get(int fd, struct expandtree *expandtree)
{
FILE *fp;
- struct alias alias;
char *buf, *lbuf, *p, *cp;
size_t len;
size_t nbaliases = 0;
int quoted;
- struct expand_node expnode;
+ struct expandnode expnode;
fp = fdopen(fd, "r");
if (fp == NULL)
@@ -84,19 +83,18 @@ forwards_get(int fd, struct expandtree *expandtree)
buf = cp;
cp = p;
- if (! alias_parse(&alias, buf)) {
+ bzero(&expnode, sizeof (struct expandnode));
+ if (! alias_parse(&expnode, buf)) {
log_debug("bad entry in ~/.forward");
continue;
}
- if (alias.type == EXPAND_INCLUDE) {
+ if (expnode.type == EXPAND_INCLUDE) {
log_debug(
"includes are forbidden in ~/.forward");
continue;
}
- bzero(&expnode, sizeof(struct expand_node));
- alias_to_expand_node(&expnode, &alias);
expandtree_increment_node(expandtree, &expnode);
nbaliases++;
} while (*cp != '\0');
diff --git a/usr.sbin/smtpd/lka.c b/usr.sbin/smtpd/lka.c
index 0dfdbe2990d..a17af939a2e 100644
--- a/usr.sbin/smtpd/lka.c
+++ b/usr.sbin/smtpd/lka.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lka.c,v 1.106 2010/04/21 21:47:38 gilles Exp $ */
+/* $OpenBSD: lka.c,v 1.107 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -48,7 +48,7 @@ void lka_setup_events(struct smtpd *);
void lka_disable_events(struct smtpd *);
void lka_expand_pickup(struct smtpd *, struct lkasession *);
int lka_expand_resume(struct smtpd *, struct lkasession *);
-int lka_resolve_node(struct smtpd *, char *tag, struct path *, struct expand_node *);
+int lka_resolve_node(struct smtpd *, char *tag, struct path *, struct expandnode *);
int lka_verify_mail(struct smtpd *, struct path *);
struct rule *ruleset_match(struct smtpd *, char *, struct path *, struct sockaddr_storage *);
int lka_resolve_path(struct smtpd *, struct lkasession *, struct path *);
@@ -133,7 +133,7 @@ lka_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
map = map_findbyname(env, "secrets");
if (map == NULL)
fatalx("lka: secrets map not found");
- map_secret = map_lookup(env, map->m_id, secret->host, K_SECRETS);
+ map_secret = map_lookup(env, map->m_id, secret->host, K_SECRET);
log_debug("lka: %s secret lookup (%d)", secret->host,
map_secret != NULL);
secret->secret[0] = '\0';
@@ -494,7 +494,7 @@ lka_expand(char *buf, size_t len, struct path *path)
}
int
-lka_resolve_node(struct smtpd *env, char *tag, struct path *path, struct expand_node *expnode)
+lka_resolve_node(struct smtpd *env, char *tag, struct path *path, struct expandnode *expnode)
{
struct path psave = *path;
@@ -600,7 +600,7 @@ int
lka_expand_resume(struct smtpd *env, struct lkasession *lkasession)
{
u_int8_t done = 1;
- struct expand_node *expnode = NULL;
+ struct expandnode *expnode = NULL;
struct path *lkasessionpath = NULL;
struct path path, *pathp = NULL;
@@ -777,7 +777,7 @@ lkasession_cmp(struct lkasession *s1, struct lkasession *s2)
void
lka_clear_expandtree(struct expandtree *expandtree)
{
- struct expand_node *expnode;
+ struct expandnode *expnode;
while ((expnode = RB_ROOT(expandtree)) != NULL) {
expandtree_remove_node(expandtree, expnode);
diff --git a/usr.sbin/smtpd/makemap.c b/usr.sbin/smtpd/makemap.c
index e3217833a4a..18677dc06cd 100644
--- a/usr.sbin/smtpd/makemap.c
+++ b/usr.sbin/smtpd/makemap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: makemap.c,v 1.25 2010/04/21 21:40:56 gilles Exp $ */
+/* $OpenBSD: makemap.c,v 1.26 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -239,11 +239,8 @@ parse_mapentry(char *line, size_t len, size_t lineno)
{
DBT key;
DBT val;
- DBT domkey;
- DBT domval;
char *keyp;
char *valp;
- char *domp;
keyp = line;
while (isspace((int)*keyp))
@@ -283,21 +280,6 @@ parse_mapentry(char *line, size_t len, size_t lineno)
return 0;
}
- /* add key for domain */
- if ((domp = strrchr(key.data, '@')) != NULL) {
- domkey.data = domp + 1;
- domkey.size = strlen(domkey.data) + 1;
-
- domval.data = "<empty>";
- domval.size = strlen(domval.data) + 1;
-
- if (db->put(db, &domkey, &domval, 0) == -1) {
- warn("dbput");
- return 0;
- }
- }
-
-
dbputs++;
free(val.data);
@@ -358,13 +340,18 @@ make_plain(DBT *val, char *text)
int
make_aliases(DBT *val, char *text)
{
- struct alias a;
+ struct expandnode expnode;
char *subrcpt;
char *endp;
+ char *origtext;
val->data = NULL;
val->size = 0;
+ origtext = strdup(text);
+ if (origtext == NULL)
+ fatal("strdup");
+
while ((subrcpt = strsep(&text, ",")) != NULL) {
/* subrcpt: strip initial whitespace. */
while (isspace((int)*subrcpt))
@@ -377,16 +364,13 @@ make_aliases(DBT *val, char *text)
while (subrcpt < endp && isspace((int)*endp))
*endp-- = '\0';
- if (! alias_parse(&a, subrcpt))
+ bzero(&expnode, sizeof(struct expandnode));
+ if (! alias_parse(&expnode, subrcpt))
goto error;
-
- val->data = realloc(val->data, val->size + sizeof(a));
- if (val->data == NULL)
- err(1, "get_targets: realloc");
- memcpy((u_int8_t *)val->data + val->size, &a, sizeof(a));
- val->size += sizeof(a);
}
+ val->data = origtext;
+ val->size = strlen(origtext) + 1;
return (val->size);
error:
diff --git a/usr.sbin/smtpd/map.c b/usr.sbin/smtpd/map.c
index 1586a0c1062..4dc3dfff778 100644
--- a/usr.sbin/smtpd/map.c
+++ b/usr.sbin/smtpd/map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: map.c,v 1.15 2010/04/21 21:47:38 gilles Exp $ */
+/* $OpenBSD: map.c,v 1.16 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -90,7 +90,7 @@ map_lookup(struct smtpd *env, objid_t mapid, char *key, enum map_kind kind)
goto end;
if (parser->extract != NULL) {
- ret = parser->extract(result, len);
+ ret = parser->extract(key, result, len);
free(result);
}
diff --git a/usr.sbin/smtpd/map_parser.c b/usr.sbin/smtpd/map_parser.c
index ca999a0a124..6ad702b6d0e 100644
--- a/usr.sbin/smtpd/map_parser.c
+++ b/usr.sbin/smtpd/map_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: map_parser.c,v 1.2 2010/04/21 21:47:38 gilles Exp $ */
+/* $OpenBSD: map_parser.c,v 1.3 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2010 Gilles Chehade <gilles@openbsd.org>
@@ -36,13 +36,15 @@
struct map_parser *map_parser_lookup(enum map_kind);
-void *map_parse_secret(char *, size_t);
+void *map_parse_secret(char *, char *, size_t);
+void *map_parse_alias(char *, char *, size_t);
+void *map_parse_virtual(char *, char *, size_t);
struct map_parser map_parsers[] = {
- { K_NONE, NULL },
- { K_ALIASES, NULL },
- { K_VIRTUAL, NULL },
- { K_SECRETS, map_parse_secret }
+ { K_NONE, NULL },
+ { K_ALIAS, map_parse_alias },
+ { K_VIRTUAL, map_parse_virtual },
+ { K_SECRET, map_parse_secret }
};
struct map_parser *
@@ -61,7 +63,7 @@ map_parser_lookup(enum map_kind kind)
}
void *
-map_parse_secret(char *line, size_t len)
+map_parse_secret(char *key, char *line, size_t len)
{
struct map_secret *map_secret = NULL;
char *p;
@@ -102,3 +104,89 @@ err:
free(map_secret);
return NULL;
}
+
+void *
+map_parse_alias(char *key, char *line, size_t len)
+{
+ char *subrcpt;
+ char *endp;
+ struct map_alias *map_alias = NULL;
+ struct expandnode expnode;
+
+ map_alias = calloc(1, sizeof(struct map_alias));
+ if (map_alias == NULL)
+ fatalx("calloc");
+
+ while ((subrcpt = strsep(&line, ",")) != NULL) {
+ /* subrcpt: strip initial whitespace. */
+ while (isspace((int)*subrcpt))
+ ++subrcpt;
+ if (*subrcpt == '\0')
+ goto error;
+
+ /* subrcpt: strip trailing whitespace. */
+ endp = subrcpt + strlen(subrcpt) - 1;
+ while (subrcpt < endp && isspace((int)*endp))
+ *endp-- = '\0';
+
+ bzero(&expnode, sizeof (struct expandnode));
+ if (! alias_parse(&expnode, subrcpt))
+ goto error;
+
+ expandtree_increment_node(&map_alias->expandtree, &expnode);
+ map_alias->nbnodes++;
+ }
+
+ return map_alias;
+
+error:
+ /* free elements in map_alias->expandtree */
+ expandtree_free_nodes(&map_alias->expandtree);
+ free(map_alias);
+ return NULL;
+}
+
+void *
+map_parse_virtual(char *key, char *line, size_t len)
+{
+ char *subrcpt;
+ char *endp;
+ struct map_virtual *map_virtual = NULL;
+ struct expandnode expnode;
+
+ map_virtual = calloc(1, sizeof(struct map_virtual));
+ if (map_virtual == NULL)
+ fatalx("calloc");
+
+ /* domain key, discard value */
+ if (strchr(key, '@') == NULL)
+ return map_virtual;
+
+ while ((subrcpt = strsep(&line, ",")) != NULL) {
+ /* subrcpt: strip initial whitespace. */
+ while (isspace((int)*subrcpt))
+ ++subrcpt;
+ if (*subrcpt == '\0')
+ goto error;
+
+ /* subrcpt: strip trailing whitespace. */
+ endp = subrcpt + strlen(subrcpt) - 1;
+ while (subrcpt < endp && isspace((int)*endp))
+ *endp-- = '\0';
+
+ bzero(&expnode, sizeof (struct expandnode));
+ if (! alias_parse(&expnode, subrcpt))
+ goto error;
+
+ expandtree_increment_node(&map_virtual->expandtree, &expnode);
+ map_virtual->nbnodes++;
+ }
+
+ return map_virtual;
+
+error:
+ /* free elements in map_virtual->expandtree */
+ expandtree_free_nodes(&map_virtual->expandtree);
+ free(map_virtual);
+ return NULL;
+}
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index 3bced957a50..2be94da3244 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.180 2010/04/22 12:56:33 jacekm Exp $ */
+/* $OpenBSD: smtpd.h,v 1.181 2010/04/27 09:49:23 gilles Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -251,9 +251,9 @@ enum map_src {
enum map_kind {
K_NONE,
- K_ALIASES,
+ K_ALIAS,
K_VIRTUAL,
- K_SECRETS
+ K_SECRET
};
enum mapel_type {
@@ -295,12 +295,7 @@ struct map_backend {
struct map_parser {
enum map_kind kind;
- void *(*extract)(char *, size_t);
-};
-
-struct map_secret {
- char username[MAX_LINE_SIZE];
- char password[MAX_LINE_SIZE];
+ void *(*extract)(char *, char *, size_t);
};
enum cond_type {
@@ -409,18 +404,15 @@ enum expand_flags {
F_EXPAND_DONE
};
-struct expand_node {
- RB_ENTRY(expand_node) entry;
+struct expandnode {
+ RB_ENTRY(expandnode) entry;
size_t refcnt;
enum expand_flags flags;
enum expand_type type;
union path_data u;
};
-struct alias {
- enum expand_type type;
- union path_data u;
-};
+RB_HEAD(expandtree, expandnode);
enum message_type {
T_MDA_MESSAGE = 0x1,
@@ -787,7 +779,7 @@ struct lkasession {
struct path path;
struct deliverylist deliverylist;
- RB_HEAD(expandtree, expand_node) expandtree;
+ struct expandtree expandtree;
u_int8_t iterations;
u_int32_t pending;
@@ -840,6 +832,24 @@ struct mta_session {
};
+/* maps return structures */
+struct map_secret {
+ char username[MAX_LINE_SIZE];
+ char password[MAX_LINE_SIZE];
+};
+
+struct map_alias {
+ size_t nbnodes;
+ struct expandtree expandtree;
+};
+
+struct map_virtual {
+ size_t nbnodes;
+ struct expandtree expandtree;
+};
+
+
+
extern void (*imsg_callback)(struct smtpd *, struct imsgev *, struct imsg *);
/* aliases.c */
@@ -848,8 +858,7 @@ int aliases_get(struct smtpd *, objid_t, struct expandtree *, char *);
int aliases_vdomain_exists(struct smtpd *, objid_t, char *);
int aliases_virtual_exist(struct smtpd *, objid_t, struct path *);
int aliases_virtual_get(struct smtpd *, objid_t, struct expandtree *, struct path *);
-int alias_parse(struct alias *, char *);
-void alias_to_expand_node(struct expand_node *, struct alias *);
+int alias_parse(struct expandnode *, char *);
/* authenticate.c */
int authenticate_user(char *, char *);
@@ -882,12 +891,13 @@ void dns_query_ptr(struct smtpd *, struct sockaddr_storage *,
void dns_async(struct smtpd *, struct imsgev *, int,
struct dns *);
/* expand.c */
-int expand_cmp(struct expand_node *, struct expand_node *);
-void expandtree_increment_node(struct expandtree *, struct expand_node *);
-void expandtree_decrement_node(struct expandtree *, struct expand_node *);
-void expandtree_remove_node(struct expandtree *, struct expand_node *);
-struct expand_node *expandtree_lookup(struct expandtree *, struct expand_node *);
-RB_PROTOTYPE(expandtree, expand_node, nodes, expand_cmp);
+int expand_cmp(struct expandnode *, struct expandnode *);
+void expandtree_increment_node(struct expandtree *, struct expandnode *);
+void expandtree_decrement_node(struct expandtree *, struct expandnode *);
+void expandtree_remove_node(struct expandtree *, struct expandnode *);
+struct expandnode *expandtree_lookup(struct expandtree *, struct expandnode *);
+void expandtree_free_nodes(struct expandtree *);
+RB_PROTOTYPE(expandtree, expandnode, nodes, expand_cmp);
/* forward.c */
int forwards_get(int, struct expandtree *);