diff options
-rw-r--r-- | usr.sbin/smtpd/parse.y | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y index 0a4413fac7c..d150902f29b 100644 --- a/usr.sbin/smtpd/parse.y +++ b/usr.sbin/smtpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.33 2009/05/20 14:29:44 gilles Exp $ */ +/* $OpenBSD: parse.y,v 1.34 2009/05/21 01:27:48 gilles Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -98,6 +98,7 @@ int host(const char *, const char *, struct listenerlist *, int, in_port_t, u_int8_t); int interface(const char *, const char *, struct listenerlist *, int, in_port_t, u_int8_t); +void set_localaddrs(void); typedef struct { union { @@ -814,51 +815,8 @@ from : FROM mapref { } | /* empty */ { struct map *m; - struct mapel *me; - struct sockaddr_in *ssin; - struct sockaddr_in6 *ssin6; - - 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_flags |= F_DYNAMIC|F_USED; - m->m_type = T_SINGLE; - - TAILQ_INIT(&m->m_contents); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - me->me_key.med_addr.bits = 0; - ssin = (struct sockaddr_in *)&me->me_key.med_addr.ss; - ssin->sin_family = AF_INET; - if (inet_pton(AF_INET, "127.0.0.1", &ssin->sin_addr) != 1) { - free(me); - free(m); - YYERROR; - } - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); - - if ((me = calloc(1, sizeof(*me))) == NULL) - fatal("out of memory"); - me->me_key.med_addr.bits = 0; - ssin6 = (struct sockaddr_in6 *)&me->me_key.med_addr.ss; - ssin6->sin6_family = AF_INET6; - if (inet_pton(AF_INET6, "::1", &ssin6->sin6_addr) != 1) { - 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_findbyname(conf, "localhost"); $$ = m->m_id; } ; @@ -1275,6 +1233,7 @@ 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)); @@ -1287,6 +1246,12 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) free(conf->sc_maps); return 0; } + if ((m = calloc(1, sizeof(*m))) == NULL) { + log_warn("cannot allocate memory"); + free(conf->sc_maps); + free(conf->sc_rules); + return 0; + } errors = 0; last_map_id = 0; @@ -1311,6 +1276,18 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) topfile = file; /* + * declare special "local" map + */ + m->m_id = last_map_id++; + if (strlcpy(m->m_name, "localhost", sizeof(m->m_name)) + >= sizeof(m->m_name)) + fatal("strlcpy"); + m->m_type = T_LIST; + TAILQ_INIT(&m->m_contents); + TAILQ_INSERT_TAIL(conf->sc_maps, m, m_entry); + set_localaddrs(); + + /* * parse configuration */ setservent(1); @@ -1628,3 +1605,51 @@ interface(const char *s, const char *cert, struct listenerlist *al, int max, in_ return ret; } + +void +set_localaddrs(void) +{ + struct ifaddrs *ifap, *p; + struct sockaddr_storage ss; + struct sockaddr_in *sain; + struct sockaddr_in6 *sin6; + struct map *m; + struct mapel *me; + + if (getifaddrs(&ifap) == -1) + fatal("getifaddrs"); + + m = map_findbyname(conf, "localhost"); + + for (p = ifap; p != NULL; p = p->ifa_next) { + switch (p->ifa_addr->sa_family) { + case AF_INET: + 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"); + me->me_key.med_addr.bits = 0; + me->me_key.med_addr.ss = *(struct sockaddr_storage *)sain; + TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); + + 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"); + me->me_key.med_addr.bits = 0; + me->me_key.med_addr.ss = *(struct sockaddr_storage *)sin6; + TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); + + break; + } + } + + freeifaddrs(ifap); +} |