diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2012-09-17 20:19:19 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2012-09-17 20:19:19 +0000 |
commit | 79d9163e078bf085b994c63ae7bf596c4df665de (patch) | |
tree | 2637bcbaacbe7b7bdbf311c69232a25eb2f3847b | |
parent | 7ae5b4210777fba0c46da75f69da33ac20326c6f (diff) |
Add map_create() and map_add() helpers. Simplify the config parser by a
great deal.
While there, rename the default "localhost" map to "<localhost>" to make
it look more internal, and create a single "<anyhost>" map referenced by
"from all" rules, instead of creating a dynamic one for each of them.
ok gilles@ chl@
-rw-r--r-- | usr.sbin/smtpd/map.c | 59 | ||||
-rw-r--r-- | usr.sbin/smtpd/parse.y | 287 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 4 |
3 files changed, 94 insertions, 256 deletions
diff --git a/usr.sbin/smtpd/map.c b/usr.sbin/smtpd/map.c index 4758adc14a3..57497954fd2 100644 --- a/usr.sbin/smtpd/map.c +++ b/usr.sbin/smtpd/map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: map.c,v 1.28 2012/08/30 18:25:44 gilles Exp $ */ +/* $OpenBSD: map.c,v 1.29 2012/09/17 20:19:18 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -22,6 +22,7 @@ #include <sys/param.h> #include <sys/socket.h> +#include <err.h> #include <event.h> #include <imsg.h> #include <stdio.h> @@ -39,6 +40,8 @@ extern struct map_backend map_backend_db; extern struct map_backend map_backend_stdio; /* extern struct map_backend map_backend_ldap; */ +static objid_t last_map_id = 0; + struct map_backend * map_backend_lookup(enum map_src source) { @@ -135,3 +138,57 @@ map_compare(objid_t mapid, char *key, enum map_kind kind, backend->close(hdl); return ret; } + +struct map* +map_create(enum map_kind kind, const char *name) +{ + struct map *m; + size_t n; + + if (name && map_findbyname(name)) + errx(1, "map_create: map \"%s\" already defined", name); + + m = xcalloc(1, sizeof(*m), "map_create"); + m->m_src = kind; + m->m_id = last_map_id++; + if (m->m_id == INT_MAX) + errx(1, "map_create: too many maps defined"); + + if (name == NULL) + snprintf(m->m_name, sizeof(m->m_name), "<dynamic:%u>", m->m_id); + else { + n = strlcpy(m->m_name, name, sizeof(m->m_name)); + if (n >= sizeof(m->m_name)) + errx(1, "map_create: map name too long"); + } + + TAILQ_INIT(&m->m_contents); + + TAILQ_INSERT_TAIL(env->sc_maps, m, m_entry); + + return (m); +} + +void +map_add(struct map *m, const char *key, const char * val) +{ + struct mapel *me; + size_t n; + + if (m->m_src != S_NONE) + errx(1, "map_add: cannot add to map"); + + me = xcalloc(1, sizeof(*me), "map_add"); + n = strlcpy(me->me_key.med_string, key, sizeof(me->me_key.med_string)); + if (n >= sizeof(me->me_key.med_string)) + errx(1, "map_add: key too long"); + + if (val) { + n = strlcpy(me->me_val.med_string, key, + sizeof(me->me_val.med_string)); + if (n >= sizeof(me->me_val.med_string)) + errx(1, "map_add: value too long"); + } + + TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); +} diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y index 06678a461ae..440608d9e66 100644 --- a/usr.sbin/smtpd/parse.y +++ b/usr.sbin/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.99 2012/09/15 15:12:11 eric Exp $ */ +/* $OpenBSD: parse.y,v 1.100 2012/09/17 20:19:18 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -88,11 +88,9 @@ char *symget(const char *); struct smtpd *conf = NULL; static int errors = 0; -objid_t last_map_id = 1; struct map *map = NULL; struct rule *rule = NULL; TAILQ_HEAD(condlist, cond) *conditions = NULL; -struct mapel_list *contents = NULL; struct listener *host_v4(const char *, in_port_t); struct listener *host_v6(const char *, in_port_t); @@ -293,9 +291,7 @@ expire : EXPIRE STRING { ; credentials : AUTH STRING { - struct map *m; - - if ((m = map_findbyname($2)) == NULL) { + if ((map_findbyname($2)) == NULL) { yyerror("no such map: %s", $2); free($2); YYERROR; @@ -469,36 +465,8 @@ mapsource : PLAIN STRING { mapopt : SOURCE mapsource { } map : MAP STRING { - struct map *m; - - TAILQ_FOREACH(m, conf->sc_maps, m_entry) - if (strcmp(m->m_name, $2) == 0) - break; - - if (m != NULL) { - yyerror("map %s defined twice", $2); - free($2); - YYERROR; - } - if ((m = calloc(1, sizeof(*m))) == NULL) - fatal("out of memory"); - if (strlcpy(m->m_name, $2, sizeof(m->m_name)) >= - sizeof(m->m_name)) { - yyerror("map name truncated"); - free(m); - free($2); - YYERROR; - } - - m->m_id = last_map_id++; - - if (m->m_id == INT_MAX) { - yyerror("too many maps defined"); - free($2); - free(m); - YYERROR; - } - map = m; + map = map_create(S_NONE, $2); + free($2); } optlbracket mapopt optrbracket { if (map->m_src == S_NONE) { yyerror("map %s has no source defined", $2); @@ -506,34 +474,14 @@ map : MAP STRING { map = NULL; YYERROR; } - TAILQ_INSERT_TAIL(conf->sc_maps, map, m_entry); map = NULL; } ; keyval : STRING ARROW STRING { - struct mapel *me; - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - - if (strlcpy(me->me_key.med_string, $1, - sizeof(me->me_key.med_string)) >= - sizeof(me->me_key.med_string) || - strlcpy(me->me_val.med_string, $3, - sizeof(me->me_val.med_string)) >= - sizeof(me->me_val.med_string)) { - yyerror("map elements too long: %s, %s", - $1, $3); - free(me); - free($1); - free($3); - YYERROR; - } + map_add(map, $1, $3); free($1); free($3); - - TAILQ_INSERT_TAIL(contents, me, me_entry); } ; @@ -542,21 +490,8 @@ keyval_list : keyval ; stringel : STRING { - struct mapel *me; - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - - if (strlcpy(me->me_key.med_string, $1, - sizeof(me->me_key.med_string)) >= - sizeof(me->me_key.med_string)) { - yyerror("map element too long: %s", $1); - free(me); - free($1); - YYERROR; - } + map_add(map, $1, NULL); free($1); - TAILQ_INSERT_TAIL(contents, me, me_entry); } ; @@ -566,86 +501,19 @@ string_list : stringel mapref : STRING { struct map *m; - struct mapel *me; - - if ((m = calloc(1, sizeof(*m))) == NULL) - fatal("out of memory"); - m->m_id = last_map_id++; - if (m->m_id == INT_MAX) { - yyerror("too many maps defined"); - free(m); - YYERROR; - } - if (! bsnprintf(m->m_name, sizeof(m->m_name), - "<dynamic(%u)>", m->m_id)) - fatal("snprintf"); - m->m_src = S_NONE; - - TAILQ_INIT(&m->m_contents); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - if (strlcpy(me->me_key.med_string, $1, - sizeof(me->me_key.med_string)) >= - sizeof(me->me_key.med_string)) { - yyerror("map element too long: %s", $1); - free(me); - free($1); - YYERROR; - } - free($1); - - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - TAILQ_INSERT_TAIL(conf->sc_maps, m, m_entry); + m = map_create(S_NONE, NULL); + map_add(m, $1, NULL); $$ = m->m_id; } | '(' { - struct map *m; - - if ((m = calloc(1, sizeof(*m))) == NULL) - fatal("out of memory"); - - m->m_id = last_map_id++; - if (m->m_id == INT_MAX) { - yyerror("too many maps defined"); - free(m); - YYERROR; - } - if (! bsnprintf(m->m_name, sizeof(m->m_name), - "<dynamic(%u)>", m->m_id)) - fatal("snprintf"); - - TAILQ_INIT(&m->m_contents); - contents = &m->m_contents; - map = m; - + map = map_create(S_NONE, NULL); } string_list ')' { - TAILQ_INSERT_TAIL(conf->sc_maps, map, m_entry); $$ = map->m_id; } | '{' { - struct map *m; - - if ((m = calloc(1, sizeof(*m))) == NULL) - fatal("out of memory"); - - m->m_id = last_map_id++; - if (m->m_id == INT_MAX) { - yyerror("too many maps defined"); - free(m); - YYERROR; - } - if (! bsnprintf(m->m_name, sizeof(m->m_name), - "<dynamic(%u)>", m->m_id)) - fatal("snprintf"); - - TAILQ_INIT(&m->m_contents); - contents = &m->m_contents; - map = m; - + map = map_create(S_NONE, NULL); } keyval_list '}' { - TAILQ_INSERT_TAIL(conf->sc_maps, map, m_entry); $$ = map->m_id; } | MAP STRING { @@ -707,7 +575,12 @@ condition : DOMAIN mapref alias { | LOCAL alias { struct cond *c; struct map *m; - struct mapel *me; + char hostname[MAXHOSTNAMELEN]; + + if (gethostname(hostname, sizeof hostname) == -1) { + yyerror("gethostname() failed"); + YYERROR; + } if ($2) { if ((m = map_findbyname($2)) == NULL) { @@ -718,40 +591,9 @@ condition : DOMAIN mapref alias { rule->r_amap = m->m_id; } - if ((m = calloc(1, sizeof(*m))) == NULL) - fatal("out of memory"); - m->m_id = last_map_id++; - if (m->m_id == INT_MAX) { - yyerror("too many maps defined"); - free(m); - YYERROR; - } - if (! bsnprintf(m->m_name, sizeof(m->m_name), - "<dynamic(%u)>", m->m_id)) - fatal("snprintf"); - - TAILQ_INIT(&m->m_contents); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - - (void)strlcpy(me->me_key.med_string, "localhost", - sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - - if (gethostname(me->me_key.med_string, - sizeof(me->me_key.med_string)) == -1) { - yyerror("gethostname() failed"); - free(me); - free(m); - YYERROR; - } - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - - TAILQ_INSERT_TAIL(conf->sc_maps, m, m_entry); + m = map_create(S_NONE, NULL); + map_add(m, "localhost", NULL); + map_add(m, hostname, NULL); if ((c = calloc(1, sizeof *c)) == NULL) fatal("out of memory"); @@ -976,55 +818,13 @@ from : FROM mapref { $$ = $2; } | FROM ALL { - struct map *m; - struct mapel *me; - - if ((m = calloc(1, sizeof(*m))) == NULL) - fatal("out of memory"); - m->m_id = last_map_id++; - if (m->m_id == INT_MAX) { - yyerror("too many maps defined"); - free(m); - YYERROR; - } - if (! bsnprintf(m->m_name, sizeof(m->m_name), - "<dynamic(%u)>", m->m_id)) - fatal("snprintf"); - - TAILQ_INIT(&m->m_contents); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - (void)strlcpy(me->me_key.med_string, "local", - sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - (void)strlcpy(me->me_key.med_string, "0.0.0.0/0", - sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - (void)strlcpy(me->me_key.med_string, "::/0", - sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - - TAILQ_INSERT_TAIL(conf->sc_maps, m, m_entry); - $$ = m->m_id; + $$ = map_findbyname("<anyhost>")->m_id; } | FROM LOCAL { - struct map *m; - - m = map_findbyname("localhost"); - $$ = m->m_id; + $$ = map_findbyname("<localhost>")->m_id; } | /* empty */ { - struct map *m; - - m = map_findbyname("localhost"); - $$ = m->m_id; + $$ = map_findbyname("<localhost>")->m_id; } ; @@ -1506,7 +1306,6 @@ int parse_config(struct smtpd *x_conf, const char *filename, int opts) { struct sym *sym, *next; - struct map *m; conf = x_conf; bzero(conf, sizeof(*conf)); @@ -1518,26 +1317,22 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) conf->sc_listeners = calloc(1, sizeof(*conf->sc_listeners)); conf->sc_ssl = calloc(1, sizeof(*conf->sc_ssl)); conf->sc_filters = calloc(1, sizeof(*conf->sc_filters)); - m = calloc(1, sizeof(*m)); if (conf->sc_maps == NULL || conf->sc_rules == NULL || conf->sc_listeners == NULL || conf->sc_ssl == NULL || - conf->sc_filters == NULL || - m == NULL) { + conf->sc_filters == NULL) { log_warn("cannot allocate memory"); free(conf->sc_maps); free(conf->sc_rules); free(conf->sc_listeners); free(conf->sc_ssl); free(conf->sc_filters); - free(m); return (-1); } errors = 0; - last_map_id = 1; map = NULL; rule = NULL; @@ -1556,20 +1351,13 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) if ((file = pushfile(filename, 0)) == NULL) { purge_config(PURGE_EVERYTHING); - free(m); return (-1); } topfile = file; /* - * declare special "local" map + * declare special "localhost" and "anyhost" maps */ - m->m_id = last_map_id++; - if (strlcpy(m->m_name, "localhost", sizeof(m->m_name)) - >= sizeof(m->m_name)) - fatal("strlcpy"); - TAILQ_INIT(&m->m_contents); - TAILQ_INSERT_TAIL(conf->sc_maps, m, m_entry); set_localaddrs(); /* @@ -1897,16 +1685,17 @@ set_localaddrs(void) struct sockaddr_in *sain; struct sockaddr_in6 *sin6; struct map *m; - struct mapel *me; + + m = map_create(S_NONE, "<anyhost>"); + map_add(m, "local", NULL); + map_add(m, "0.0.0.0/0", NULL); + map_add(m, "::/0", NULL); if (getifaddrs(&ifap) == -1) fatal("getifaddrs"); - m = map_findbyname("localhost"); - - me = xcalloc(1, sizeof *me, "set_localaddrs"); - strlcpy(me->me_key.med_string, "local", sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); + m = map_create(S_NONE, "<localhost>"); + map_add(m, "local", NULL); for (p = ifap; p != NULL; p = p->ifa_next) { if (p->ifa_addr == NULL) @@ -1916,24 +1705,14 @@ set_localaddrs(void) sain = (struct sockaddr_in *)&ss; *sain = *(struct sockaddr_in *)p->ifa_addr; sain->sin_len = sizeof(struct sockaddr_in); - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - (void)strlcpy(me->me_key.med_string, - ss_to_text(&ss), - sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); + map_add(m, ss_to_text(&ss), NULL); break; case AF_INET6: sin6 = (struct sockaddr_in6 *)&ss; *sin6 = *(struct sockaddr_in6 *)p->ifa_addr; sin6->sin6_len = sizeof(struct sockaddr_in6); - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - (void)strlcpy(me->me_key.med_string, - ss_to_text(&ss), - sizeof(me->me_key.med_string)); - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); + map_add(m, ss_to_text(&ss), NULL); break; } } diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index a9122c3bf39..80e07910730 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.351 2012/09/16 16:54:55 chl Exp $ */ +/* $OpenBSD: smtpd.h,v 1.352 2012/09/17 20:19:18 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -1031,6 +1031,8 @@ void *map_lookup(objid_t, char *, enum map_kind); int map_compare(objid_t, char *, enum map_kind, int (*)(char *, char *)); struct map *map_find(objid_t); struct map *map_findbyname(const char *); +struct map *map_create(enum map_kind, const char *); +void map_add(struct map *, const char *, const char *); /* mda.c */ |