diff options
Diffstat (limited to 'smtpd')
56 files changed, 2281 insertions, 1968 deletions
diff --git a/smtpd/Makefile.am b/smtpd/Makefile.am index 5bcda8c5..55bf9147 100644 --- a/smtpd/Makefile.am +++ b/smtpd/Makefile.am @@ -23,19 +23,20 @@ sbin_PROGRAMS= smtpd smtpctl pkglibexec_PROGRAMS= makemap -makemap_SOURCES= parse.y makemap.c aliases.c expand.c log.c util.c map.c \ - map_static.c map_db.c map_file.c tree.c +makemap_SOURCES= parse.y makemap.c aliases.c expand.c log.c util.c \ + table.c table_db.c table_getpwnam.c table_static.c \ + tree.c makemap_CFLAGS= -DNO_IO smtpd_SOURCES= aliases.c auth.c bounce.c compress_backend.c config.c \ control.c delivery.c dns.c envelope.c expand.c \ - forward.c iobuf.c ioev.c lka.c lka_session.c log.c map.c\ + forward.c iobuf.c ioev.c lka.c lka_session.c log.c \ mda.c mfa.c mfa_session.c mta.c mta_session.c parse.y \ queue.c queue_backend.c ruleset.c \ scheduler.c scheduler_backend.c smtp.c smtp_session.c \ - smtpd.c ssl.c ssl_privsep.c stat_backend.c tree.c \ - user.c util.c + smtpd.c ssl.c ssl_privsep.c stat_backend.c table.c \ + tree.c user.c util.c # backends smtpd_SOURCES+= auth_bsd.c smtpd_SOURCES+= auth_pwd.c @@ -44,14 +45,14 @@ smtpd_SOURCES+= delivery_filename.c smtpd_SOURCES+= delivery_maildir.c smtpd_SOURCES+= delivery_mbox.c smtpd_SOURCES+= delivery_mda.c -smtpd_SOURCES+= map_db.c -smtpd_SOURCES+= map_file.c -smtpd_SOURCES+= map_static.c smtpd_SOURCES+= queue_fsqueue.c smtpd_SOURCES+= queue_ram.c smtpd_SOURCES+= scheduler_ramqueue.c smtpd_SOURCES+= stat_ramstat.c #smtpd_SOURCES+= stat_sqlite.c +smtpd_SOURCES+= table_db.c +smtpd_SOURCES+= table_getpwnam.c +smtpd_SOURCES+= table_static.c smtpd_SOURCES+= user_pwd.c # resolver diff --git a/smtpd/aliases.c b/smtpd/aliases.c index 7d0a0af6..763b2c5a 100644 --- a/smtpd/aliases.c +++ b/smtpd/aliases.c @@ -49,95 +49,98 @@ static int alias_is_filename(struct expandnode *, const char *, size_t); static int alias_is_include(struct expandnode *, const char *, size_t); int -aliases_get(objid_t mapid, struct expand *expand, const char *username) +aliases_get(objid_t id, struct expand *expand, const char *username) { - struct map_alias *map_alias; - struct expandnode *xn; - char buf[MAX_LOCALPART_SIZE]; - size_t nbaliases; + struct table_alias *table_alias = NULL; + struct expandnode *xn; + char buf[MAX_LOCALPART_SIZE]; + size_t nbaliases; + int ret; xlowercase(buf, username, sizeof(buf)); - map_alias = map_lookup(mapid, buf, K_ALIAS); - if (map_alias == NULL) - return (errno ? -1 : 0); + ret = table_lookup(id, buf, K_ALIAS, (void **)&table_alias); + if (ret <= 0) + return ret; - /* foreach node in map_alias expandtree, we merge */ + /* foreach node in table_alias expandtree, we merge */ nbaliases = 0; - RB_FOREACH(xn, expandtree, &map_alias->expand.tree) { + RB_FOREACH(xn, expandtree, &table_alias->expand.tree) { if (xn->type == EXPAND_INCLUDE) - nbaliases += aliases_expand_include(expand, xn->u.buffer); + nbaliases += aliases_expand_include(expand, + xn->u.buffer); else { expand_insert(expand, xn); nbaliases++; } } - expand_free(&map_alias->expand); - free(map_alias); + expand_free(&table_alias->expand); + free(table_alias); log_debug("debug: aliases_get: returned %zd aliases", nbaliases); return nbaliases; } int -aliases_virtual_get(objid_t mapid, struct expand *expand, +aliases_virtual_get(objid_t id, struct expand *expand, const struct mailaddr *maddr) { - struct map_virtual *map_virtual; + struct table_virtual *table_virtual = NULL; struct expandnode *xn; char buf[MAX_LINE_SIZE]; char *pbuf = buf; int nbaliases; + int ret; if (! bsnprintf(buf, sizeof(buf), "%s@%s", maddr->user, maddr->domain)) return 0; xlowercase(buf, buf, sizeof(buf)); + + ret = table_lookup(id, buf, K_VIRTUAL, (void **)&table_virtual); + if (ret < 0) + return (-1); - map_virtual = map_lookup(mapid, buf, K_VIRTUAL); - if (map_virtual == NULL) { - if (errno) - return (-1); + if (ret == 0) { pbuf = strchr(buf, '@'); - map_virtual = map_lookup(mapid, pbuf, K_VIRTUAL); + ret = table_lookup(id, pbuf, K_VIRTUAL, (void **)&table_virtual); } - if (map_virtual == NULL) - return (errno ? -1 : 0); + if (ret <= 0) + return ret; - /* foreach node in map_virtual expand, we merge */ + /* foreach node in table_virtual expand, we merge */ nbaliases = 0; - RB_FOREACH(xn, expandtree, &map_virtual->expand.tree) { + RB_FOREACH(xn, expandtree, &table_virtual->expand.tree) { if (xn->type == EXPAND_INCLUDE) - nbaliases += aliases_expand_include(expand, xn->u.buffer); + nbaliases += aliases_expand_include(expand, + xn->u.buffer); else { expand_insert(expand, xn); nbaliases++; } } - expand_free(&map_virtual->expand); - free(map_virtual); - log_debug("debug: aliases_virtual_get: '%s' resolved to %d nodes", pbuf, nbaliases); + expand_free(&table_virtual->expand); + free(table_virtual); + log_debug("debug: aliases_virtual_get: '%s' resolved to %d nodes", + pbuf, nbaliases); return nbaliases; } int -aliases_vdomain_exists(objid_t mapid, const char *hostname) +aliases_vdomain_exists(objid_t id, const char *hostname) { - struct map_virtual *map_virtual; - char buf[MAXHOSTNAMELEN]; + char buf[MAXHOSTNAMELEN]; + int ret; xlowercase(buf, hostname, sizeof(buf)); - map_virtual = map_lookup(mapid, buf, K_VIRTUAL); - if (map_virtual == NULL) - return (errno ? -1 : 0); + ret = table_lookup(id, buf, K_VIRTUAL, NULL); + if (ret <= 0) + return ret; - /* XXX - for now the map API always allocate */ + /* XXX - for now the table API always allocate */ log_debug("debug: aliases_vdomain_exist: '%s' exists", hostname); - expand_free(&map_virtual->expand); - free(map_virtual); - return 1; } @@ -163,9 +166,9 @@ aliases_expand_include(struct expand *expand, const char *filename) continue; } - if (! alias_parse(&xn, line)) { - log_warnx("warn: could not parse include entry \"%s\".", line); - } + if (! alias_parse(&xn, line)) + log_warnx("warn: could not parse include entry \"%s\".", + line); if (xn.type == EXPAND_INCLUDE) log_warnx("warn: nested inclusion is not supported."); @@ -259,7 +262,8 @@ alias_is_address(struct expandnode *alias, const char *line, size_t len) /* scan pre @ for disallowed chars */ *domain++ = '\0'; strlcpy(alias->u.mailaddr.user, line, sizeof(alias->u.mailaddr.user)); - strlcpy(alias->u.mailaddr.domain, domain, sizeof(alias->u.mailaddr.domain)); + strlcpy(alias->u.mailaddr.domain, domain, + sizeof(alias->u.mailaddr.domain)); while (*line) { char allowedset[] = "!#$%*/?|^{}`~&'+-=_."; diff --git a/smtpd/bounce.c b/smtpd/bounce.c index 297c748e..37ce100c 100644 --- a/smtpd/bounce.c +++ b/smtpd/bounce.c @@ -142,7 +142,7 @@ bounce_run(uint64_t id, int fd) { struct bounce *bounce; int msgfd; - + log_trace(TRACE_BOUNCE, "bounce: run %016" PRIx64 " fd %i", id, fd); bounce = tree_xpop(&bounces_by_uid, id); @@ -218,7 +218,8 @@ bounce_drain() tree_xset(&bounces_by_uid, bounce->id, bounce); - log_debug("debug: bounce: %p: requesting enqueue socket with id 0x%016" PRIx64, + log_debug("debug: bounce: %p: requesting enqueue socket " + "with id 0x%016" PRIx64, bounce, bounce->id); imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_ENQUEUE, @@ -244,7 +245,7 @@ bounce_send(struct bounce *bounce, const char *fmt, ...) iobuf_xfqueue(&bounce->iobuf, "bounce_send", "%s\n", p); - free(p); + free(p); } /* This can simplified once we support PIPELINING */ @@ -255,7 +256,7 @@ bounce_next(struct bounce *bounce) char *line; size_t len, s; - switch(bounce->state) { + switch (bounce->state) { case BOUNCE_EHLO: bounce_send(bounce, "EHLO %s", env->sc_hostname); bounce->state = BOUNCE_MAIL; @@ -305,7 +306,8 @@ bounce_next(struct bounce *bounce) line = evp->errorline; if (strlen(line) > 4 && (*line == '1' || *line == '6')) line += 4; - iobuf_xfqueue(&bounce->iobuf, "bounce_next: DATA_NOTICE", + iobuf_xfqueue(&bounce->iobuf, + "bounce_next: DATA_NOTICE", "Recipient: %s@%s\n" "Reason: %s\n", evp->dest.user, evp->dest.domain, line); @@ -391,12 +393,12 @@ bounce_status(struct bounce *bounce, const char *fmt, ...) evp->retry++; envelope_set_errormsg(evp, "%s", status); queue_envelope_update(evp); - imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], msg, 0, 0, -1, - evp, sizeof *evp); + imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], msg, 0, + 0, -1, evp, sizeof *evp); } else { queue_envelope_delete(evp); - imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], msg, 0, 0, -1, - &evp->id, sizeof evp->id); + imsg_compose_event(env->sc_ievs[PROC_SCHEDULER], msg, 0, + 0, -1, &evp->id, sizeof evp->id); } TAILQ_REMOVE(&bounce->envelopes, evp, entry); free(evp); @@ -454,7 +456,7 @@ bounce_io(struct io *io, int evt) } iobuf_normalize(&bounce->iobuf); break; - } + } log_trace(TRACE_BOUNCE, "bounce: %p: <<< %s", bounce, line); diff --git a/smtpd/config.c b/smtpd/config.c index 05e2542c..b251d682 100644 --- a/smtpd/config.c +++ b/smtpd/config.c @@ -60,7 +60,7 @@ void purge_config(uint8_t what) { struct listener *l; - struct map *m; + struct table *t; struct rule *r; struct ssl *s; struct mapel *me; @@ -73,17 +73,17 @@ purge_config(uint8_t what) free(env->sc_listeners); env->sc_listeners = NULL; } - if (what & PURGE_MAPS) { - while ((m = TAILQ_FIRST(env->sc_maps)) != NULL) { - TAILQ_REMOVE(env->sc_maps, m, m_entry); - while ((me = TAILQ_FIRST(&m->m_contents))) { - TAILQ_REMOVE(&m->m_contents, me, me_entry); + if (what & PURGE_TABLES) { + while ((t = TAILQ_FIRST(env->sc_tables)) != NULL) { + TAILQ_REMOVE(env->sc_tables, t, t_entry); + while ((me = TAILQ_FIRST(&t->t_contents))) { + TAILQ_REMOVE(&t->t_contents, me, me_entry); free(me); } - free(m); + free(t); } - free(env->sc_maps); - env->sc_maps = NULL; + free(env->sc_tables); + env->sc_tables = NULL; } if (what & PURGE_RULES) { while ((r = TAILQ_FIRST(env->sc_rules)) != NULL) { @@ -118,8 +118,8 @@ init_pipes(void) /* * find out how many instances of this peer there are. */ - if (i >= j || env->sc_instances[i] == 0|| - env->sc_instances[j] == 0) + if (i >= j || env->sc_instances[i] == 0 || + env->sc_instances[j] == 0) continue; if (env->sc_instances[i] > 1 && @@ -201,7 +201,7 @@ config_peers(struct peer *p, uint peercount) if (dst == smtpd_process) fatal("config_peers: cannot peer with oneself"); - + env->sc_ievs[dst] = xcalloc(env->sc_instances[dst], sizeof(struct imsgev), "config_peers"); diff --git a/smtpd/control.c b/smtpd/control.c index b575f483..7ff514b2 100644 --- a/smtpd/control.c +++ b/smtpd/control.c @@ -104,7 +104,7 @@ control_imsg(struct imsgev *iev, struct imsg *imsg) if (c == NULL) return; imsg_compose_event(&c->iev, IMSG_SCHEDULER_MESSAGES, 0, - 0, -1, imsg->data, imsg->hdr.len - sizeof imsg->hdr); + 0, -1, imsg->data, imsg->hdr.len-sizeof imsg->hdr); return; } } @@ -115,7 +115,7 @@ control_imsg(struct imsgev *iev, struct imsg *imsg) if (c == NULL) return; imsg_compose_event(&c->iev, IMSG_SCHEDULER_ENVELOPES, 0, - 0, -1, imsg->data, imsg->hdr.len - sizeof imsg->hdr); + 0, -1, imsg->data, imsg->hdr.len-sizeof imsg->hdr); return; } } @@ -217,7 +217,8 @@ control(void) } (void)umask(old_umask); - if (chmod(SMTPD_SOCKET, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) == -1) { + if (chmod(SMTPD_SOCKET, + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) == -1) { (void)unlink(SMTPD_SOCKET); fatal("control: chmod"); } @@ -420,7 +421,7 @@ control_dispatch_ext(int fd, short event, void *arg) uint64_t id; struct stat_kv *kvp; char *key; - struct stat_value val; + struct stat_value val; size_t len; if (getpeereid(fd, &euid, &egid) == -1) @@ -458,8 +459,8 @@ control_dispatch_ext(int fd, short event, void *arg) case IMSG_SMTP_ENQUEUE: if (env->sc_flags & (SMTPD_SMTP_PAUSED | SMTPD_CONFIGURING | SMTPD_EXITING)) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } imsg_compose_event(env->sc_ievs[PROC_SMTP], @@ -469,7 +470,8 @@ control_dispatch_ext(int fd, short event, void *arg) case IMSG_STATS: if (euid) goto badcred; - imsg_compose_event(&c->iev, IMSG_STATS, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_STATS, 0, 0, -1, + NULL, 0); break; case IMSG_DIGEST: @@ -522,9 +524,11 @@ control_dispatch_ext(int fd, short event, void *arg) memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); - imsg_compose_event(env->sc_ievs[PROC_PARENT], IMSG_CTL_VERBOSE, - 0, 0, -1, &verbose, sizeof(verbose)); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(env->sc_ievs[PROC_PARENT], + IMSG_CTL_VERBOSE, 0, 0, -1, &verbose, + sizeof(verbose)); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_QUEUE_PAUSE_MDA: @@ -532,15 +536,16 @@ control_dispatch_ext(int fd, short event, void *arg) goto badcred; if (env->sc_flags & SMTPD_MDA_PAUSED) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } log_info("info: mda paused"); env->sc_flags |= SMTPD_MDA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_QUEUE_PAUSE_MTA: @@ -548,15 +553,16 @@ control_dispatch_ext(int fd, short event, void *arg) goto badcred; if (env->sc_flags & SMTPD_MTA_PAUSED) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } log_info("info: mta paused"); env->sc_flags |= SMTPD_MTA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_SMTP_PAUSE: @@ -564,15 +570,16 @@ control_dispatch_ext(int fd, short event, void *arg) goto badcred; if (env->sc_flags & SMTPD_SMTP_PAUSED) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } log_info("info: smtp paused"); env->sc_flags |= SMTPD_SMTP_PAUSED; - imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_PAUSE, - 0, 0, -1, NULL, 0); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(env->sc_ievs[PROC_SMTP], + IMSG_SMTP_PAUSE, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_QUEUE_RESUME_MDA: @@ -580,15 +587,16 @@ control_dispatch_ext(int fd, short event, void *arg) goto badcred; if (! (env->sc_flags & SMTPD_MDA_PAUSED)) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } log_info("info: mda resumed"); env->sc_flags &= ~SMTPD_MDA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_QUEUE_RESUME_MTA: @@ -596,15 +604,16 @@ control_dispatch_ext(int fd, short event, void *arg) goto badcred; if (!(env->sc_flags & SMTPD_MTA_PAUSED)) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } log_info("info: mta resumed"); env->sc_flags &= ~SMTPD_MTA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_SMTP_RESUME: @@ -612,15 +621,16 @@ control_dispatch_ext(int fd, short event, void *arg) goto badcred; if (!(env->sc_flags & SMTPD_SMTP_PAUSED)) { - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, - NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, + -1, NULL, 0); break; } log_info("info: smtp resumed"); env->sc_flags &= ~SMTPD_SMTP_PAUSED; - imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_RESUME, - 0, 0, -1, NULL, 0); - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); + imsg_compose_event(env->sc_ievs[PROC_SMTP], + IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; case IMSG_SCHEDULER_MESSAGES: @@ -661,17 +671,19 @@ control_dispatch_ext(int fd, short event, void *arg) NULL, 0); break; - case IMSG_LKA_UPDATE_MAP: + case IMSG_LKA_UPDATE_TABLE: if (euid) goto badcred; - /* map name too long */ + /* table name too long */ len = strlen(imsg.data); if (len >= MAX_LINE_SIZE) goto invalid; - imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_UPDATE_MAP, - 0, 0, -1, imsg.data, len + 1); + imsg_compose_event(env->sc_ievs[PROC_LKA], + IMSG_LKA_UPDATE_TABLE, 0, 0, -1, imsg.data, len+1); + imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, + NULL, 0); break; default: diff --git a/smtpd/delivery_filename.c b/smtpd/delivery_filename.c index 52238ade..750fd4bf 100644 --- a/smtpd/delivery_filename.c +++ b/smtpd/delivery_filename.c @@ -57,7 +57,7 @@ struct delivery_backend delivery_backend_filename = { static void delivery_filename_open(struct deliver *deliver) { - struct stat sb; + struct stat sb; time_t now; size_t len; int fd; @@ -66,7 +66,7 @@ delivery_filename_open(struct deliver *deliver) char *msg; int n; -#define error(m) { msg = m; goto err; } +#define error(m) { msg = m; goto err; } #define error2(m) { msg = m; goto err2; } setproctitle("file delivery"); diff --git a/smtpd/delivery_maildir.c b/smtpd/delivery_maildir.c index 66ebefde..6f795908 100644 --- a/smtpd/delivery_maildir.c +++ b/smtpd/delivery_maildir.c @@ -60,7 +60,7 @@ delivery_maildir_open(struct deliver *deliver) char *msg; int n; -#define error(m) { msg = m; goto err; } +#define error(m) { msg = m; goto err; } #define error2(m) { msg = m; goto err2; } setproctitle("maildir delivery"); diff --git a/smtpd/delivery_mbox.c b/smtpd/delivery_mbox.c index 153bb285..58622225 100644 --- a/smtpd/delivery_mbox.c +++ b/smtpd/delivery_mbox.c @@ -56,7 +56,7 @@ static void delivery_mbox_open(struct deliver *deliver) { char *environ_new[2]; - + environ_new[0] = "PATH=" _PATH_DEFPATH; environ_new[1] = (char *)NULL; environ = environ_new; diff --git a/smtpd/delivery_mda.c b/smtpd/delivery_mda.c index e4509479..187894e9 100644 --- a/smtpd/delivery_mda.c +++ b/smtpd/delivery_mda.c @@ -52,7 +52,7 @@ static void delivery_mda_open(struct deliver *deliver) { char *environ_new[2]; - + environ_new[0] = "PATH=" _PATH_DEFPATH; environ_new[1] = (char *)NULL; environ = environ_new; diff --git a/smtpd/dns.c b/smtpd/dns.c index c167fe32..e6de6461 100644 --- a/smtpd/dns.c +++ b/smtpd/dns.c @@ -103,8 +103,8 @@ dns_query_mx(char *host, char *backup, int port, uint64_t id) query.port = port; query.id = id; - imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_DNS_MX, 0, 0, -1, &query, - sizeof(query)); + imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_DNS_MX, 0, 0, -1, + &query, sizeof(query)); } void @@ -116,8 +116,8 @@ dns_query_ptr(struct sockaddr_storage *ss, uint64_t id) query.ss = *ss; query.id = id; - imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_DNS_PTR, 0, 0, -1, &query, - sizeof(query)); + imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_DNS_PTR, 0, 0, -1, + &query, sizeof(query)); } /* LKA interface */ @@ -135,7 +135,8 @@ dns_async(struct imsgev *asker, int type, struct dns *query) log_debug("debug: dns: lookup host \"%s\"", query->host); if (sockaddr_from_str((struct sockaddr*)&query->ss, PF_UNSPEC, query->host) == 0) { - log_debug("debug: dns: \"%s\" is an IP address", query->host); + log_debug("debug: dns: \"%s\" is an IP address", + query->host); query->error = DNS_OK; dns_reply(query, IMSG_DNS_HOST); dns_reply(query, IMSG_DNS_HOST_END); @@ -187,7 +188,7 @@ static void dns_asr_event_set(struct dnssession *s, struct async_res *ar) { struct timeval tv = { 0, 0 }; - + tv.tv_usec = ar->ar_timeout * 1000; event_set(&s->ev, ar->ar_fd, ar->ar_cond == ASYNC_READ ? EV_READ : EV_WRITE, dns_asr_handler, s); @@ -199,7 +200,7 @@ dns_asr_handler(int fd, short event, void *arg) { struct dnssession *s = arg; - switch(s->query.type) { + switch (s->query.type) { case IMSG_DNS_HOST: dns_asr_dispatch_host(s); break; @@ -298,7 +299,7 @@ next: if (mx == NULL || (s->preference != -1 && s->preference <= mx->preference)) { if (mx) - log_debug("debug: dns: ignoring mx with lower preference"); + log_debug("debug: dns: ignoring mx with < pri"); if (s->mxfound) query->error = DNS_OK; dns_reply(query, IMSG_DNS_HOST_END); @@ -325,7 +326,8 @@ next: if (ar.ar_gai_errno == 0) { for (ai = ar.ar_addrinfo; ai; ai = ai->ai_next) { memcpy(&query->ss, ai->ai_addr, ai->ai_addrlen); - log_debug("debug: dns: got address %s", ss_to_text(&query->ss)); + log_debug("debug: dns: got address %s", + ss_to_text(&query->ss)); dns_reply(query, IMSG_DNS_HOST); s->mxfound++; } @@ -379,7 +381,7 @@ dnssession_destroy(struct dnssession *s) stat_decrement("lka.session", 1); event_del(&s->ev); - while((mx = TAILQ_FIRST(&s->mx))) { + while ((mx = TAILQ_FIRST(&s->mx))) { TAILQ_REMOVE(&s->mx, mx, entry); free(mx->host); free(mx); @@ -397,7 +399,8 @@ dnssession_mx_insert(struct dnssession *s, const char *host, int preference) mx->host = xstrdup(host, "dnssession_mx_insert"); mx->preference = preference; - log_debug("debug: dns: found mx \"%s\" with preference %i", host, preference); + log_debug("debug: dns: found mx \"%s\" with preference %i", + host, preference); TAILQ_FOREACH(e, &s->mx, entry) { if (mx->preference <= e->preference) { diff --git a/smtpd/enqueue.c b/smtpd/enqueue.c index abdbce51..9e1d7dfb 100644 --- a/smtpd/enqueue.c +++ b/smtpd/enqueue.c @@ -143,7 +143,7 @@ qp_encoded_write(FILE *fp, char *buf, size_t len) fprintf(fp, "=3D"); else if (*buf == ' ' || *buf == '\t') { char *p = buf; - + while (*p != '\n') { if (*p != ' ' && *p != '\t') break; @@ -228,7 +228,7 @@ enqueue(int argc, char *argv[]) build_from(fake_from, pw); - while(argc > 0) { + while (argc > 0) { rcpt_add(argv[0]); argv++; argc--; @@ -281,7 +281,7 @@ enqueue(int argc, char *argv[]) if (!msg.saw_from) send_line(fout, 0, "From: %s%s<%s>\n", msg.fromname ? msg.fromname : "", - msg.fromname ? " " : "", + msg.fromname ? " " : "", msg.from); /* add Date */ @@ -298,14 +298,17 @@ enqueue(int argc, char *argv[]) if (!msg.saw_mime_version) send_line(fout, 0, "MIME-Version: 1.0\n"); if (!msg.saw_content_type) - send_line(fout, 0, "Content-Type: text/plain; charset=unknown-8bit\n"); + send_line(fout, 0, "Content-Type: text/plain; " + "charset=unknown-8bit\n"); if (!msg.saw_content_disposition) send_line(fout, 0, "Content-Disposition: inline\n"); if (!msg.saw_content_transfer_encoding) - send_line(fout, 0, "Content-Transfer-Encoding: quoted-printable\n"); + send_line(fout, 0, "Content-Transfer-Encoding: " + "quoted-printable\n"); } if (!msg.saw_user_agent) - send_line(fout, 0, "User-Agent: OpenSMTPD enqueuer (Demoosh)\n"); + send_line(fout, 0, "User-Agent: OpenSMTPD enqueuer (%s)\n", + "Demoosh"); /* add separating newline */ if (noheader) @@ -331,7 +334,8 @@ enqueue(int argc, char *argv[]) line = buf; - if (msg.saw_content_transfer_encoding || noheader || inheaders || !msg.need_linesplit) { + if (msg.saw_content_transfer_encoding || noheader || + inheaders || !msg.need_linesplit) { send_line(fout, 0, "%.*s", (int)len, line); if (inheaders && buf[0] == '\n') inheaders = 0; @@ -345,7 +349,8 @@ enqueue(int argc, char *argv[]) break; } else { - qp_encoded_write(fout, line, LINESPLIT - 2 - dotted); + qp_encoded_write(fout, line, + LINESPLIT - 2 - dotted); send_line(fout, 0, "=\n"); line += LINESPLIT - 2 - dotted; len -= LINESPLIT - 2 - dotted; @@ -353,10 +358,10 @@ enqueue(int argc, char *argv[]) } while (len); } send_line(fout, verbose, ".\n"); - get_responses(fout, 1); + get_responses(fout, 1); send_line(fout, verbose, "QUIT\n"); - get_responses(fout, 1); + get_responses(fout, 1); fclose(fp); fclose(fout); @@ -375,7 +380,7 @@ get_responses(FILE *fin, int n) if ((e = ferror(fin))) errx(1, "ferror: %i", e); - while(n) { + while (n) { buf = fgetln(fin, &len); if (buf == NULL && ferror(fin)) err(1, "fgetln"); @@ -577,7 +582,7 @@ parse_addr(char *s, size_t len, int is_from) if (!pstate.comment && !pstate.quote && !pstate.esc) { if (s[pos] == ':') { /* group */ - for(pos++; pos < len && WSP(s[pos]); pos++) + for (pos++; pos < len && WSP(s[pos]); pos++) ; /* nothing */ pstate.wpos = 0; } @@ -636,7 +641,7 @@ parse_addr_terminal(int is_from) else rcpt_add(pstate.buf); pstate.wpos = 0; - } + } } static char * diff --git a/smtpd/envelope.c b/smtpd/envelope.c index f56b32e4..843f6b36 100644 --- a/smtpd/envelope.c +++ b/smtpd/envelope.c @@ -112,7 +112,8 @@ envelope_load_buffer(struct envelope *ep, char *buf, size_t buflen) EVP_MTA_RELAY_PORT, EVP_MTA_RELAY_CERT, EVP_MTA_RELAY_FLAGS, - EVP_MTA_RELAY_AUTHMAP + EVP_MTA_RELAY_AUTHMAP, + EVP_MTA_RELAY_AUTHTABLE }; char *field, *nextline; size_t len; @@ -194,7 +195,7 @@ envelope_dump_buffer(struct envelope *ep, char *dest, size_t len) EVP_MTA_RELAY_HOST, EVP_MTA_RELAY_PORT, EVP_MTA_RELAY_CERT, - EVP_MTA_RELAY_AUTHMAP, + EVP_MTA_RELAY_AUTHTABLE, EVP_MTA_RELAY_FLAGS }; enum envelope_field *pfields = NULL; @@ -308,6 +309,8 @@ envelope_ascii_field_name(enum envelope_field field) return "mta-relay-cert"; case EVP_MTA_RELAY_AUTHMAP: return "mta-relay-authmap"; + case EVP_MTA_RELAY_AUTHTABLE: + return "mta-relay-authtable"; } return NULL; @@ -365,8 +368,9 @@ envelope_ascii_load(enum envelope_field field, struct envelope *ep, char *buf) return ascii_load_mta_relay_flags(&ep->agent.mta.relay.flags, buf); case EVP_MTA_RELAY_AUTHMAP: - return ascii_load_string(ep->agent.mta.relay.authmap, buf, - sizeof ep->agent.mta.relay.authmap); + case EVP_MTA_RELAY_AUTHTABLE: + return ascii_load_string(ep->agent.mta.relay.authtable, buf, + sizeof ep->agent.mta.relay.authtable); case EVP_CTIME: return ascii_load_time(&ep->creation, buf); case EVP_EXPIRE: @@ -425,7 +429,9 @@ envelope_ascii_dump(enum envelope_field field, struct envelope *ep, return ascii_dump_mta_relay_flags(ep->agent.mta.relay.flags, buf, len); case EVP_MTA_RELAY_AUTHMAP: - return ascii_dump_string(ep->agent.mta.relay.authmap, + return 1; + case EVP_MTA_RELAY_AUTHTABLE: + return ascii_dump_string(ep->agent.mta.relay.authtable, buf, len); case EVP_CTIME: return ascii_dump_time(ep->creation, buf, len); diff --git a/smtpd/filter_api.c b/smtpd/filter_api.c index fc377cec..deacc1bf 100644 --- a/smtpd/filter_api.c +++ b/smtpd/filter_api.c @@ -37,31 +37,40 @@ static struct filter_internals { struct event ev; struct imsgbuf ibuf; - enum filter_status (*connect_cb)(uint64_t, struct filter_connect *, void *); + enum filter_status + (*connect_cb)(uint64_t, struct filter_connect *, void *); void *connect_cb_arg; - enum filter_status (*helo_cb)(uint64_t, struct filter_helo *, void *); + enum filter_status + (*helo_cb)(uint64_t, struct filter_helo *, void *); void *helo_cb_arg; - enum filter_status (*ehlo_cb)(uint64_t, struct filter_helo *, void *); + enum filter_status + (*ehlo_cb)(uint64_t, struct filter_helo *, void *); void *ehlo_cb_arg; - enum filter_status (*mail_cb)(uint64_t, struct filter_mail *, void *); + enum filter_status + (*mail_cb)(uint64_t, struct filter_mail *, void *); void *mail_cb_arg; - enum filter_status (*rcpt_cb)(uint64_t, struct filter_rcpt *, void *); + enum filter_status + (*rcpt_cb)(uint64_t, struct filter_rcpt *, void *); void *rcpt_cb_arg; - enum filter_status (*dataline_cb)(uint64_t, struct filter_dataline *, void *); + enum filter_status + (*dataline_cb)(uint64_t, struct filter_dataline *, void *); void *dataline_cb_arg; - enum filter_status (*quit_cb)(uint64_t, void *); + enum filter_status + (*quit_cb)(uint64_t, void *); void *quit_cb_arg; - enum filter_status (*close_cb)(uint64_t, void *); + enum filter_status + (*close_cb)(uint64_t, void *); void *close_cb_arg; - enum filter_status (*rset_cb)(uint64_t, void *); + enum filter_status + (*rset_cb)(uint64_t, void *); void *rset_cb_arg; } fi; @@ -89,55 +98,64 @@ filter_loop(void) } void -filter_register_connect_callback(enum filter_status (*cb)(uint64_t, struct filter_connect *, void *), void *cb_arg) +filter_register_connect_callback(enum filter_status + (*cb)(uint64_t, struct filter_connect *, void *), void *cb_arg) { filter_register_callback(FILTER_CONNECT, cb, cb_arg); } void -filter_register_helo_callback(enum filter_status (*cb)(uint64_t, struct filter_helo *, void *), void *cb_arg) +filter_register_helo_callback(enum filter_status + (*cb)(uint64_t, struct filter_helo *, void *), void *cb_arg) { filter_register_callback(FILTER_HELO, cb, cb_arg); } void -filter_register_ehlo_callback(enum filter_status (*cb)(uint64_t, struct filter_helo *, void *), void *cb_arg) +filter_register_ehlo_callback(enum filter_status + (*cb)(uint64_t, struct filter_helo *, void *), void *cb_arg) { filter_register_callback(FILTER_EHLO, cb, cb_arg); } void -filter_register_mail_callback(enum filter_status (*cb)(uint64_t, struct filter_mail *, void *), void *cb_arg) +filter_register_mail_callback(enum filter_status + (*cb)(uint64_t, struct filter_mail *, void *), void *cb_arg) { filter_register_callback(FILTER_MAIL, cb, cb_arg); } void -filter_register_rcpt_callback(enum filter_status (*cb)(uint64_t, struct filter_rcpt *, void *), void *cb_arg) +filter_register_rcpt_callback(enum filter_status + (*cb)(uint64_t, struct filter_rcpt *, void *), void *cb_arg) { filter_register_callback(FILTER_RCPT, cb, cb_arg); } void -filter_register_dataline_callback(enum filter_status (*cb)(uint64_t, struct filter_dataline *, void *), void *cb_arg) +filter_register_dataline_callback(enum filter_status + (*cb)(uint64_t, struct filter_dataline *, void *), void *cb_arg) { filter_register_callback(FILTER_DATALINE, cb, cb_arg); } void -filter_register_quit_callback(enum filter_status (*cb)(uint64_t, void *), void *cb_arg) +filter_register_quit_callback(enum filter_status + (*cb)(uint64_t, void *), void *cb_arg) { filter_register_callback(FILTER_QUIT, cb, cb_arg); } void -filter_register_close_callback(enum filter_status (*cb)(uint64_t, void *), void *cb_arg) +filter_register_close_callback(enum filter_status + (*cb)(uint64_t, void *), void *cb_arg) { filter_register_callback(FILTER_CLOSE, cb, cb_arg); } void -filter_register_rset_callback(enum filter_status (*cb)(uint64_t, void *), void *cb_arg) +filter_register_rset_callback(enum filter_status + (*cb)(uint64_t, void *), void *cb_arg) { filter_register_callback(FILTER_RSET, cb, cb_arg); } @@ -289,7 +307,7 @@ filter_handler(int fd, short event, void *p) if (fi.rset_cb == NULL) goto ignore; ret = fi.rset_cb(fm.cl_id, fi.rset_cb_arg); - break; + break; default: errx(1, "unsupported imsg"); diff --git a/smtpd/filter_api.h b/smtpd/filter_api.h index 6740db2c..dc463730 100644 --- a/smtpd/filter_api.h +++ b/smtpd/filter_api.h @@ -53,7 +53,7 @@ struct filter_connect { struct filter_helo { char helohost[MAXHOSTNAMELEN]; }; - + struct filter_mail { char user[MAX_LOCALPART_SIZE]; char domain[MAX_DOMAINPART_SIZE]; @@ -79,7 +79,7 @@ union filter_union { struct filter_msg { uint64_t id; /* set by smtpd(8) */ uint64_t cl_id; /* set by smtpd(8) */ - int8_t code; + int8_t code; uint8_t version; enum filter_type type; union filter_union u; @@ -89,13 +89,22 @@ struct filter_msg { void filter_init(void); void filter_loop(void); -void filter_register_connect_callback(enum filter_status (*)(uint64_t, struct filter_connect *, void *), void *); -void filter_register_helo_callback(enum filter_status (*)(uint64_t, struct filter_helo *, void *), void *); -void filter_register_ehlo_callback(enum filter_status (*)(uint64_t, struct filter_helo *, void *), void *); -void filter_register_mail_callback(enum filter_status (*)(uint64_t, struct filter_mail *, void *), void *); -void filter_register_rcpt_callback(enum filter_status (*)(uint64_t, struct filter_rcpt *, void *), void *); -void filter_register_dataline_callback(enum filter_status (*)(uint64_t, struct filter_dataline *, void *), void *); -void filter_register_quit_callback(enum filter_status (*)(uint64_t, void *), void *); -void filter_register_close_callback(enum filter_status (*)(uint64_t, void *), void *); -void filter_register_rset_callback(enum filter_status (*)(uint64_t, void *), void *); +void filter_register_connect_callback(enum filter_status + (*)(uint64_t, struct filter_connect *, void *), void *); +void filter_register_helo_callback(enum filter_status + (*)(uint64_t, struct filter_helo *, void *), void *); +void filter_register_ehlo_callback(enum filter_status + (*)(uint64_t, struct filter_helo *, void *), void *); +void filter_register_mail_callback(enum filter_status + (*)(uint64_t, struct filter_mail *, void *), void *); +void filter_register_rcpt_callback(enum filter_status + (*)(uint64_t, struct filter_rcpt *, void *), void *); +void filter_register_dataline_callback(enum filter_status + (*)(uint64_t, struct filter_dataline *, void *), void *); +void filter_register_quit_callback(enum filter_status + (*)(uint64_t, void *), void *); +void filter_register_close_callback(enum filter_status + (*)(uint64_t, void *), void *); +void filter_register_rset_callback(enum filter_status + (*)(uint64_t, void *), void *); diff --git a/smtpd/iobuf.c b/smtpd/iobuf.c index 3b4a91bc..5fd9f677 100644 --- a/smtpd/iobuf.c +++ b/smtpd/iobuf.c @@ -49,7 +49,7 @@ iobuf_init(struct iobuf *io, size_t size, size_t max) if (size == 0) size = max; - + if (size > max) return (-1); @@ -70,7 +70,7 @@ iobuf_clear(struct iobuf *io) if (io->buf) free(io->buf); - while((q = io->outq)) { + while ((q = io->outq)) { io->outq = q->next; free(q); } @@ -84,7 +84,7 @@ iobuf_drain(struct iobuf *io, size_t n) struct ioqbuf *q; size_t left = n; - while((q = io->outq) && left) { + while ((q = io->outq) && left) { if ((q->wpos - q->rpos) > left) { q->rpos += left; left = 0; @@ -182,7 +182,7 @@ iobuf_getline(struct iobuf *iobuf, size_t *rlen) return (buf); } - return (NULL); + return (NULL); } void @@ -233,9 +233,9 @@ ioqbuf_alloc(struct iobuf *io, size_t len) return (NULL); q->rpos = 0; - q->wpos = 0; - q->size = len; - q->next = NULL; + q->wpos = 0; + q->size = len; + q->next = NULL; q->buf = (char *)(q) + sizeof(*q); if (io->outqlast == NULL) @@ -297,13 +297,13 @@ iobuf_queuev(struct iobuf *io, const struct iovec *iov, int iovcnt) size_t len = 0; char *buf; - for(i = 0; i < iovcnt; i++) + for (i = 0; i < iovcnt; i++) len += iov[i].iov_len; if ((buf = iobuf_reserve(io, len)) == NULL) return (-1); - for(i = 0; i < iovcnt; i++) { + for (i = 0; i < iovcnt; i++) { if (iov[i].iov_len == 0) continue; memmove(buf, iov[i].iov_base, iov[i].iov_len); @@ -353,7 +353,7 @@ iobuf_write(struct iobuf *io, int fd) ssize_t n; i = 0; - for(q = io->outq; q ; q = q->next) { + for (q = io->outq; q ; q = q->next) { if (i >= IOV_MAX) break; iov[i].iov_base = q->buf + q->rpos; diff --git a/smtpd/ioev.c b/smtpd/ioev.c index b07d2708..37d1438d 100644 --- a/smtpd/ioev.c +++ b/smtpd/ioev.c @@ -116,7 +116,7 @@ io_strevent(int evt) { static char buf[32]; - switch(evt) { + switch (evt) { CASE(IO_CONNECTED); CASE(IO_TLSREADY); CASE(IO_DATAIN); @@ -425,7 +425,7 @@ io_reset(struct io *io, short events, void (*dispatch)(int, short, void*)) } else ptv = NULL; - event_add(&io->ev, ptv); + event_add(&io->ev, ptv); } size_t @@ -447,7 +447,7 @@ io_strflags(int flags) buf[0] = '\0'; - switch(flags & IO_RW) { + switch (flags & IO_RW) { case 0: strlcat(buf, "rw", sizeof buf); break; @@ -569,7 +569,7 @@ io_dispatch(int fd, short ev, void *humppa) io_callback(io, IO_DATAIN); } - leave: +leave: io_frame_leave(io); } @@ -817,7 +817,7 @@ io_reload_ssl(struct io *io) { void (*dispatch)(int, short, void*) = NULL; - switch(io->state) { + switch (io->state) { case IO_STATE_CONNECT_SSL: dispatch = io_dispatch_connect_ssl; break; diff --git a/smtpd/lka.c b/smtpd/lka.c index 19c68ec0..72359265 100644 --- a/smtpd/lka.c +++ b/smtpd/lka.c @@ -50,7 +50,7 @@ static void lka_imsg(struct imsgev *, struct imsg *); static void lka_shutdown(void); static void lka_sig_handler(int, short, void *); static int lka_verify_mail(struct mailaddr *); -static int lka_encode_credentials(char *, size_t, struct map_credentials *); +static int lka_encode_credentials(char *, size_t, struct table_credentials *); static void @@ -60,9 +60,10 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) struct secret *secret; struct mapel *mapel; struct rule *rule; - struct map *map; - struct map *mp; + struct table *table; + struct table *tp; void *tmp; + int ret; if (imsg->hdr.type == IMSG_DNS_HOST || imsg->hdr.type == IMSG_DNS_MX || imsg->hdr.type == IMSG_DNS_PTR) { @@ -106,32 +107,37 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_MTA) { switch (imsg->hdr.type) { case IMSG_LKA_SECRET: { - struct map_credentials *map_credentials; + struct table_credentials *table_credentials = NULL; secret = imsg->data; - map = map_findbyname(secret->mapname); - if (map == NULL) { - log_warn("warn: lka: credentials map %s is missing", - secret->mapname); + table = table_findbyname(secret->tablename); + if (table == NULL) { + log_warn("warn: Credentials table %s missing", + secret->tablename); imsg_compose_event(iev, IMSG_LKA_SECRET, 0, 0, -1, secret, sizeof *secret); return; } - map_credentials = map_lookup(map->m_id, secret->host, - K_CREDENTIALS); - log_debug("debug: lka: %s credentials lookup (%d)", secret->host, - map_credentials != NULL); + ret = table_lookup(table->t_id, secret->host, K_CREDENTIALS, + (void **)&table_credentials); + + log_debug("debug: lka: %s credentials lookup (%d)", + secret->host, ret); + secret->secret[0] = '\0'; - if (map_credentials == NULL) + if (ret == -1) + log_warnx("warn: error with %s credentials", + secret->host); + else if (ret == 0) log_warnx("warn: %s credentials not found", secret->host); else if (lka_encode_credentials(secret->secret, - sizeof secret->secret, map_credentials) == 0) + sizeof secret->secret, table_credentials) == 0) log_warnx("warn: %s credentials parse fail", secret->host); - imsg_compose_event(iev, IMSG_LKA_SECRET, 0, 0, -1, secret, - sizeof *secret); - free(map_credentials); + imsg_compose_event(iev, IMSG_LKA_SECRET, 0, 0, -1, + secret, sizeof *secret); + free(table_credentials); return; } } @@ -140,12 +146,12 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_PARENT) { switch (imsg->hdr.type) { case IMSG_CONF_START: - env->sc_rules_reload = xcalloc(1, sizeof *env->sc_rules, - "lka:sc_rules_reload"); - env->sc_maps_reload = xcalloc(1, sizeof *env->sc_maps, - "lka:sc_maps_reload"); + env->sc_rules_reload = xcalloc(1, + sizeof *env->sc_rules, "lka:sc_rules_reload"); + env->sc_tables_reload = xcalloc(1, + sizeof *env->sc_tables, "lka:sc_tables_reload"); TAILQ_INIT(env->sc_rules_reload); - TAILQ_INIT(env->sc_maps_reload); + TAILQ_INIT(env->sc_tables_reload); return; case IMSG_CONF_RULE: @@ -153,45 +159,46 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) TAILQ_INSERT_TAIL(env->sc_rules_reload, rule, r_entry); return; - case IMSG_CONF_MAP: - map = xmemdup(imsg->data, sizeof *map, "lka:map"); - TAILQ_INIT(&map->m_contents); - TAILQ_INSERT_TAIL(env->sc_maps_reload, map, m_entry); - - tmp = env->sc_maps; - env->sc_maps = env->sc_maps_reload; - - mp = map_open(map); - if (mp == NULL) - errx(1, "lka: could not open map \"%s\"", map->m_name); - map_close(map, mp); - - env->sc_maps = tmp; + case IMSG_CONF_TABLE: + table = xmemdup(imsg->data, sizeof *table, "lka:table"); + TAILQ_INIT(&table->t_contents); + TAILQ_INSERT_TAIL(env->sc_tables_reload, table, + t_entry); + tmp = env->sc_tables; + env->sc_tables = env->sc_tables_reload; + + tp = table_open(table); + if (tp == NULL) + errx(1, "lka: could not open table \"%s\"", + table->t_name); + table_close(table, tp); + + env->sc_tables = tmp; return; case IMSG_CONF_RULE_SOURCE: rule = TAILQ_LAST(env->sc_rules_reload, rulelist); - tmp = env->sc_maps; - env->sc_maps = env->sc_maps_reload; - rule->r_sources = map_findbyname(imsg->data); + tmp = env->sc_tables; + env->sc_tables = env->sc_tables_reload; + rule->r_sources = table_findbyname(imsg->data); if (rule->r_sources == NULL) - fatalx("lka: maps inconsistency"); - env->sc_maps = tmp; + fatalx("lka: tables inconsistency"); + env->sc_tables = tmp; return; - case IMSG_CONF_MAP_CONTENT: - map = TAILQ_LAST(env->sc_maps_reload, maplist); + case IMSG_CONF_TABLE_CONTENT: + table = TAILQ_LAST(env->sc_tables_reload, tablelist); mapel = xmemdup(imsg->data, sizeof *mapel, "lka:mapel"); - TAILQ_INSERT_TAIL(&map->m_contents, mapel, me_entry); + TAILQ_INSERT_TAIL(&table->t_contents, mapel, me_entry); return; case IMSG_CONF_END: if (env->sc_rules) purge_config(PURGE_RULES); - if (env->sc_maps) - purge_config(PURGE_MAPS); + if (env->sc_tables) + purge_config(PURGE_TABLES); env->sc_rules = env->sc_rules_reload; - env->sc_maps = env->sc_maps_reload; + env->sc_tables = env->sc_tables_reload; /* start fulfilling requests */ event_add(&env->sc_ievs[PROC_MTA]->ev, NULL); @@ -212,14 +219,14 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_CONTROL) { switch (imsg->hdr.type) { - case IMSG_LKA_UPDATE_MAP: - map = map_findbyname(imsg->data); - if (map == NULL) { - log_warnx("warn: lka: no such map \"%s\"", + case IMSG_LKA_UPDATE_TABLE: + table = table_findbyname(imsg->data); + if (table == NULL) { + log_warnx("warn: lka: no such table \"%s\"", (char *)imsg->data); return; } - map_update(map); + table_update(table); return; } } @@ -343,13 +350,14 @@ lka_verify_mail(struct mailaddr *maddr) static int lka_encode_credentials(char *dst, size_t size, - struct map_credentials *map_credentials) + struct table_credentials *table_credentials) { char *buf; int buflen; - if ((buflen = asprintf(&buf, "%c%s%c%s", '\0', map_credentials->username, - '\0', map_credentials->password)) == -1) + if ((buflen = asprintf(&buf, "%c%s%c%s", '\0', + table_credentials->username, '\0', + table_credentials->password)) == -1) fatal(NULL); if (__b64_ntop((unsigned char *)buf, buflen, dst, size) == -1) { diff --git a/smtpd/lka_session.c b/smtpd/lka_session.c index aa7080e2..f6d88c0f 100644 --- a/smtpd/lka_session.c +++ b/smtpd/lka_session.c @@ -65,8 +65,10 @@ struct lka_session { struct expandnode *node; }; -static void lka_expand(struct lka_session *, struct rule *, struct expandnode *); -static void lka_submit(struct lka_session *, struct rule *, struct expandnode *); +static void lka_expand(struct lka_session *, struct rule *, + struct expandnode *); +static void lka_submit(struct lka_session *, struct rule *, + struct expandnode *); static void lka_resume(struct lka_session *); static size_t lka_expand_format(char *, size_t, const struct envelope *); static void mailaddr_to_username(const struct mailaddr *, char *, size_t); @@ -83,7 +85,7 @@ static char *tokens[] = { "dest.user", "dest.domain", "rcpt.user", - "rcpt.domain" + "rcpt.domain" }; void @@ -162,7 +164,7 @@ lka_resume(struct lka_session *lks) goto error; /* pop next node and expand it */ - while((xn = TAILQ_FIRST(&lks->nodes))) { + while ((xn = TAILQ_FIRST(&lks->nodes))) { TAILQ_REMOVE(&lks->nodes, xn, tq_entry); lka_expand(lks, xn->rule, xn); if (lks->flags & F_WAITING) @@ -173,7 +175,7 @@ lka_resume(struct lka_session *lks) /* delivery list is empty, reject */ if (TAILQ_FIRST(&lks->deliverylist) == NULL) { - log_debug("debug: lka_done: expansion led to empty delivery list"); + log_debug("debug: lka_done: expanded to empty delivery list"); lks->flags |= F_ERROR; } error: @@ -228,7 +230,7 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) break; case EXPAND_ADDRESS: - log_debug("debug: lka_expand: expanding address: %s@%s [depth=%d]", + log_debug("debug: lka_expand: address: %s@%s [depth=%d]", xn->u.mailaddr.user, xn->u.mailaddr.domain, xn->depth); /* Pass the node through the ruleset */ @@ -250,18 +252,19 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) lks->expand.rule = rule; lks->expand.parent = xn; lks->expand.alias = 1; - r = aliases_virtual_get(rule->r_condition.c_map, + r = aliases_virtual_get(rule->r_condition.c_table, &lks->expand, &xn->u.mailaddr); if (r == -1) { lks->flags |= F_ERROR; lks->ss.code = 451; - log_debug( - "lka_expand: error in virtual alias lookup"); + log_debug("debug: lka_expand: " + "error in virtual alias lookup"); } else if (r == 0) { lks->flags |= F_ERROR; lks->ss.code = 530; - log_debug("debug: lka_expand: no aliases for virtual"); + log_debug("debug: lka_expand: " + "no aliases for virtual"); } } else { @@ -276,7 +279,8 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) break; case EXPAND_USERNAME: - log_debug("debug: lka_expand: expanding username: %s [depth=%d]", xn->u.user, xn->depth); + log_debug("debug: lka_expand: username: %s [depth=%d]", + xn->u.user, xn->depth); if (xn->sameuser) { log_debug("debug: lka_expand: same user, submitting"); @@ -288,10 +292,12 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) lks->expand.rule = rule; lks->expand.parent = xn; lks->expand.alias = 1; - if (rule->r_amap) { - r = aliases_get(rule->r_amap, &lks->expand, xn->u.user); + if (rule->r_atable) { + r = aliases_get(rule->r_atable, &lks->expand, + xn->u.user); if (r == -1) { - log_debug("debug: lka_expand: error in alias lookup"); + log_debug("debug: lka_expand: " + "error in alias lookup"); lks->flags |= F_ERROR; lks->ss.code = 451; } @@ -301,7 +307,8 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) /* a username should not exceed the size of a system user */ if (strlen(xn->u.user) >= sizeof fwreq.as_user) { - log_debug("debug: lka_expand: user-part too long to be a system user"); + log_debug("debug: lka_expand: " + "user-part too long to be a system user"); lks->flags |= F_ERROR; lks->ss.code = 530; break; @@ -310,7 +317,8 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) bzero(&u, sizeof (u)); ub = user_backend_lookup(USER_PWD); if (! ub->getbyname(&u, xn->u.user)) { - log_debug("debug: lka_expand: user-part does not match system user"); + log_debug("debug: lka_expand: " + "user-part does not match system user"); lks->flags |= F_ERROR; lks->ss.code = 530; break; @@ -332,12 +340,14 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) break; case EXPAND_FILENAME: - log_debug("debug: lka_expand: expanding filename: %s [depth=%d]", xn->u.buffer, xn->depth); + log_debug("debug: lka_expand: filename: %s [depth=%d]", + xn->u.buffer, xn->depth); lka_submit(lks, rule, xn); break; case EXPAND_FILTER: - log_debug("debug: lka_expand: expanding filter: %s [depth=%d]", xn->u.buffer, xn->depth); + log_debug("debug: lka_expand: filter: %s [depth=%d]", + xn->u.buffer, xn->depth); lka_submit(lks, rule, xn); break; } @@ -346,10 +356,11 @@ lka_expand(struct lka_session *lks, struct rule *rule, struct expandnode *xn) static struct expandnode * lka_find_ancestor(struct expandnode *xn, enum expand_type type) { - while(xn && (xn->type != type)) + while (xn && (xn->type != type)) xn = xn->parent; if (xn == NULL) { - log_warnx("warn: lka_find_ancestor: no ancestors of type %i", type); + log_warnx("warn: lka_find_ancestor: no ancestors of type %i", + type); fatalx(NULL); } return (xn); @@ -392,16 +403,17 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) if ((xn->type == EXPAND_FILTER || xn->type == EXPAND_FILENAME) && xn->alias) { strlcpy(ep->agent.mda.user.username, SMTPD_USER, - sizeof (ep->agent.mda.user.username)); + sizeof(ep->agent.mda.user.username)); } else { xn2 = lka_find_ancestor(xn, EXPAND_USERNAME); strlcpy(ep->agent.mda.user.username, xn2->u.user, - sizeof (ep->agent.mda.user.username)); + sizeof(ep->agent.mda.user.username)); } ub = user_backend_lookup(USER_PWD); - if (! ub->getbyname(&ep->agent.mda.user, ep->agent.mda.user.username)) { + if (! ub->getbyname(&ep->agent.mda.user, + ep->agent.mda.user.username)) { lks->flags |= F_ERROR; lks->ss.code = 451; free(ep); @@ -425,9 +437,9 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) tag = mailaddr_tag(&ep->dest); if (rule->r_action == A_MAILDIR && tag && tag[0]) { strlcat(ep->agent.mda.buffer, "/.", - sizeof (ep->agent.mda.buffer)); + sizeof(ep->agent.mda.buffer)); strlcat(ep->agent.mda.buffer, tag, - sizeof (ep->agent.mda.buffer)); + sizeof(ep->agent.mda.buffer)); } } else @@ -438,7 +450,8 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) lks->flags |= F_ERROR; lks->ss.code = 451; log_warnx("warn: format string error while" - " expanding for user %s", ep->agent.mda.user.username); + " expanding for user %s", + ep->agent.mda.user.username); free(ep); return; } @@ -452,7 +465,8 @@ lka_submit(struct lka_session *lks, struct rule *rule, struct expandnode *xn) static size_t -lka_expand_token(char *dest, size_t len, const char *token, const struct envelope *ep) +lka_expand_token(char *dest, size_t len, const char *token, + const struct envelope *ep) { char rtoken[MAXTOKENLEN]; const char *string; @@ -467,7 +481,8 @@ lka_expand_token(char *dest, size_t len, const char *token, const struct envelop return 0; /* token[x[:y]] -> extracts optional x and y, converts into offsets */ - if ((lbracket = strchr(rtoken, '[')) && (rbracket = strchr(rtoken, ']'))) { + if ((lbracket = strchr(rtoken, '[')) && + (rbracket = strchr(rtoken, ']'))) { /* ] before [ ... or empty */ if (rbracket < lbracket || rbracket - lbracket <= 1) return 0; @@ -475,16 +490,18 @@ lka_expand_token(char *dest, size_t len, const char *token, const struct envelop content = lbracket + 1; if ((sep = strchr(content, ':')) == NULL) - begoff = strtonum(content, -EXPAND_BUFFER, EXPAND_BUFFER, &errstr); + begoff = strtonum(content, -EXPAND_BUFFER, + EXPAND_BUFFER, &errstr); else { *sep = '\0'; if (content != sep) - begoff = strtonum(content, -EXPAND_BUFFER, EXPAND_BUFFER, &errstr); + begoff = strtonum(content, -EXPAND_BUFFER, + EXPAND_BUFFER, &errstr); sep++; if (*sep) { if (errstr == NULL) - endoff = strtonum(sep, -EXPAND_BUFFER, EXPAND_BUFFER, - &errstr); + endoff = strtonum(sep, -EXPAND_BUFFER, + EXPAND_BUFFER, &errstr); if (endoff == 0) return 0; } @@ -493,7 +510,7 @@ lka_expand_token(char *dest, size_t len, const char *token, const struct envelop return 0; } - /* token -> searches token in table and maps to expand string */ + /* token -> searches token in table and tables to expand string */ for (i = 0; i < (int)nitems(tokens); ++i) if (strcasecmp(rtoken, tokens[i]) == 0) break; @@ -527,7 +544,9 @@ lka_expand_token(char *dest, size_t len, const char *token, const struct envelop if (begoff >= i) return 0; - /* end offset beyond end of string or unspecified, make it end of string */ + /* end offset beyond end of string or unspecified, + * make it end of string + */ if (endoff >= i || endoff == 0) endoff = i; @@ -561,7 +580,7 @@ lka_expand_format(char *buf, size_t len, const struct envelope *ep) size_t ret, tmpret; if (len < sizeof tmpbuf) - fatalx("lka_expand_format: tmp buffer smaller than rule buffer"); + fatalx("lka_expand_format: tmp buffer < rule buffer"); bzero(tmpbuf, sizeof tmpbuf); pbuf = buf; @@ -570,7 +589,8 @@ lka_expand_format(char *buf, size_t len, const struct envelope *ep) /* special case: ~/ only allowed expanded at the beginning */ if (strncmp(pbuf, "~/", 2) == 0) { - tmpret = snprintf(ptmp, sizeof tmpbuf, "%s/", ep->agent.mda.user.directory); + tmpret = snprintf(ptmp, sizeof tmpbuf, "%s/", + ep->agent.mda.user.directory); if (tmpret >= sizeof tmpbuf) { log_warnx("warn: user directory for %s too large", ep->agent.mda.user.directory); @@ -606,7 +626,8 @@ lka_expand_format(char *buf, size_t len, const struct envelope *ep) return 0; *strchr(memcpy(token, pbuf+2, ebuf-pbuf-1), '}') = '\0'; - if ((exptoklen = lka_expand_token(exptok, sizeof exptok, token, ep)) == 0) + exptoklen = lka_expand_token(exptok, sizeof exptok, token, ep); + if (exptoklen == 0) return 0; if (! lowercase(exptok, exptok, sizeof exptok)) diff --git a/smtpd/log.c b/smtpd/log.c index 89346497..38cc285f 100644 --- a/smtpd/log.c +++ b/smtpd/log.c @@ -42,7 +42,7 @@ int verbose; void vlog(int, const char *, va_list); void logit(int, const char *, ...) - __attribute__ ((format (printf, 2, 3))); + __attribute__((format (printf, 2, 3))); void diff --git a/smtpd/log.h b/smtpd/log.h index 86bbbfa3..7e80929b 100644 --- a/smtpd/log.h +++ b/smtpd/log.h @@ -21,14 +21,14 @@ void log_init(int); void log_verbose(int); void log_warn(const char *, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute__((format (printf, 1, 2))); void log_warnx(const char *, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute__((format (printf, 1, 2))); void log_info(const char *, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute__((format (printf, 1, 2))); void log_debug(const char *, ...) - __attribute__ ((format (printf, 1, 2))); + __attribute__((format (printf, 1, 2))); void log_trace(int, const char *, ...) - __attribute__ ((format (printf, 2, 3))); + __attribute__((format (printf, 2, 3))); __dead void fatal(const char *); __dead void fatalx(const char *); diff --git a/smtpd/makemap.c b/smtpd/makemap.c index ab0b3cf8..92ec614b 100644 --- a/smtpd/makemap.c +++ b/smtpd/makemap.c @@ -167,15 +167,18 @@ main(int argc, char *argv[]) p = strstr(argv[1], ".db"); if (p == NULL || strcmp(p, ".db") != 0) { - if (! bsnprintf(dbname, sizeof dbname, "%s.db", argv[1])) + if (! bsnprintf(dbname, sizeof dbname, "%s.db", + argv[1])) errx(1, "database name too long"); } else { - if (strlcpy(dbname, argv[1], sizeof dbname) >= sizeof dbname) + if (strlcpy(dbname, argv[1], sizeof dbname) + >= sizeof dbname) errx(1, "database name too long"); } - execlp(execname, execname, "-d", argv[0], "-o", dbname, "-", NULL); + execlp(execname, execname, "-d", argv[0], "-o", dbname, "-", + NULL); err(1, "execlp"); } @@ -222,7 +225,8 @@ main(int argc, char *argv[]) if (strcmp(source, "-") != 0) if (fchmod(db->fd(db), sb.st_mode) == -1 || fchown(db->fd(db), sb.st_uid, sb.st_gid) == -1) { - warn("couldn't carry ownership and perms to %s", dbname); + warn("couldn't carry ownership and perms to %s", + dbname); goto bad; } @@ -389,7 +393,7 @@ parse_setentry(char *line, size_t len, size_t lineno) if (db->put(db, &key, &val, 0) == -1) { warn("dbput"); return 0; - } + } dbputs++; @@ -409,9 +413,9 @@ int make_aliases(DBT *val, char *text) { struct expandnode xn; - char *subrcpt; - char *endp; - char *origtext; + char *subrcpt; + char *endp; + char *origtext; val->data = NULL; val->size = 0; @@ -447,18 +451,18 @@ error: char * conf_aliases(char *cfgpath) { - struct map *map; + struct table *table; char *path; char *p; if (parse_config(env, cfgpath, 0)) exit(1); - map = map_findbyname("aliases"); - if (map == NULL) + table = table_findbyname("aliases"); + if (table == NULL) return (PATH_ALIASES); - path = xstrdup(map->m_config, "conf_aliases"); + path = xstrdup(table->t_config, "conf_aliases"); p = strstr(path, ".db"); if (p == NULL || strcmp(p, ".db") != 0) { return (path); @@ -473,7 +477,7 @@ usage(void) if (mode == P_NEWALIASES) fprintf(stderr, "usage: %s [-f file]\n", __progname); else - fprintf(stderr, "usage: %s [-d dbtype] [-o dbfile] [-t type] file\n", - __progname); + fprintf(stderr, "usage: %s [-d dbtype] [-o dbfile] " + "[-t type] file\n", __progname); exit(1); } diff --git a/smtpd/map.c b/smtpd/map.c deleted file mode 100644 index bf71a9dc..00000000 --- a/smtpd/map.c +++ /dev/null @@ -1,270 +0,0 @@ -/* $OpenBSD: map.c,v 1.35 2012/11/12 14:58:53 eric Exp $ */ - -/* - * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include <sys/types.h> -#include "sys-queue.h" -#include "sys-tree.h" -#include <sys/param.h> -#include <sys/socket.h> - -#include <err.h> -#include <errno.h> -#include <event.h> -#include <imsg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "smtpd.h" -#include "log.h" - -struct map_backend *map_backend_lookup(const char *); - -extern struct map_backend map_backend_static; - -extern struct map_backend map_backend_db; -extern struct map_backend map_backend_file; - -static objid_t last_map_id = 0; - -struct map_backend * -map_backend_lookup(const char *source) -{ - if (!strcmp(source, "static")) - return &map_backend_static; - if (!strcmp(source, "db")) - return &map_backend_db; - if (!strcmp(source, "file")) - return &map_backend_file; - return NULL; -} - -struct map * -map_findbyname(const char *name) -{ - struct map *m; - - TAILQ_FOREACH(m, env->sc_maps, m_entry) { - if (strcmp(m->m_name, name) == 0) - break; - } - return (m); -} - -struct map * -map_find(objid_t id) -{ - struct map *m; - - TAILQ_FOREACH(m, env->sc_maps, m_entry) { - if (m->m_id == id) - break; - } - return (m); -} - -void * -map_lookup(objid_t mapid, const char *key, enum map_kind kind) -{ - void *hdl = NULL; - char *ret = NULL; - struct map *map; - struct map_backend *backend = NULL; - - map = map_find(mapid); - if (map == NULL) { - errno = EINVAL; - return NULL; - } - - backend = map_backend_lookup(map->m_src); - hdl = backend->open(map); - if (hdl == NULL) { - log_warn("warn: map_lookup: can't open %s", map->m_config); - if (errno == 0) - errno = ENOTSUP; - return NULL; - } - - ret = backend->lookup(hdl, key, kind); - - backend->close(hdl); - errno = 0; - return ret; -} - -int -map_compare(objid_t mapid, const char *key, enum map_kind kind, - int (*func)(const char *, const char *)) -{ - void *hdl = NULL; - struct map *map; - struct map_backend *backend = NULL; - int ret; - - map = map_find(mapid); - if (map == NULL) { - errno = EINVAL; - return 0; - } - - backend = map_backend_lookup(map->m_src); - hdl = backend->open(map); - if (hdl == NULL) { - log_warn("warn: map_compare: can't open %s", map->m_config); - if (errno == 0) - errno = ENOTSUP; - return 0; - } - - ret = backend->compare(hdl, key, kind, func); - - backend->close(hdl); - errno = 0; - return ret; -} - -struct map * -map_create(const char *source, const char *name) -{ - struct map *m; - size_t n; - - if (name && map_findbyname(name)) - errx(1, "map_create: map \"%s\" already defined", name); - - if (map_backend_lookup(source) == NULL) - errx(1, "map_create: backend \"%s\" does not exist", source); - - m = xcalloc(1, sizeof(*m), "map_create"); - if (strlcpy(m->m_src, source, sizeof m->m_src) >= sizeof m->m_src) - errx(1, "map_create: map source \"%s\" too large", m->m_src); - - if (strcmp(m->m_src, "static") != 0) - m->m_type = T_DYNAMIC; - - 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_destroy(struct map *m) -{ - struct mapel *me; - - if (strcmp(m->m_src, "static") != 0) - errx(1, "map_add: cannot delete all from map"); - - while ((me = TAILQ_FIRST(&m->m_contents))) { - TAILQ_REMOVE(&m->m_contents, me, me_entry); - free(me); - } - - TAILQ_REMOVE(env->sc_maps, m, m_entry); - free(m); -} - -void -map_add(struct map *m, const char *key, const char * val) -{ - struct mapel *me; - size_t n; - - if (strcmp(m->m_src, "static") != 0) - errx(1, "map_add: cannot add to map"); - - me = xcalloc(1, sizeof(*me), "map_add"); - n = strlcpy(me->me_key, key, sizeof(me->me_key)); - if (n >= sizeof(me->me_key)) - errx(1, "map_add: key too long"); - - if (val) { - n = strlcpy(me->me_val, val, - sizeof(me->me_val)); - if (n >= sizeof(me->me_val)) - errx(1, "map_add: value too long"); - } - - TAILQ_INSERT_TAIL(&m->m_contents, me, me_entry); -} - -void -map_delete(struct map *m, const char *key) -{ - struct mapel *me; - - if (strcmp(m->m_src, "static") != 0) - errx(1, "map_add: cannot delete from map"); - - TAILQ_FOREACH(me, &m->m_contents, me_entry) { - if (strcmp(me->me_key, key) == 0) - break; - } - if (me == NULL) - return; - TAILQ_REMOVE(&m->m_contents, me, me_entry); - free(me); -} - -void * -map_open(struct map *m) -{ - struct map_backend *backend = NULL; - - backend = map_backend_lookup(m->m_src); - if (backend == NULL) - return NULL; - return backend->open(m); -} - -void -map_close(struct map *m, void *hdl) -{ - struct map_backend *backend = NULL; - - backend = map_backend_lookup(m->m_src); - backend->close(hdl); -} - - -void -map_update(struct map *m) -{ - struct map_backend *backend = NULL; - - backend = map_backend_lookup(m->m_src); - if (backend->update) - backend->update(m); -} diff --git a/smtpd/map_db.c b/smtpd/map_db.c deleted file mode 100644 index baac882e..00000000 --- a/smtpd/map_db.c +++ /dev/null @@ -1,305 +0,0 @@ -/* $OpenBSD: map_db.c,v 1.12 2012/11/12 14:58:53 eric Exp $ */ - -/* - * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include <sys/types.h> -#include "sys-queue.h" -#include "sys-tree.h" -#include <sys/param.h> -#include <sys/socket.h> - -#ifdef HAVE_DB_H -#include <db.h> -#elif defined(HAVE_DB1_DB_H) -#include <db1/db.h> -#elif defined(HAVE_DB_185_H) -#include <db_185.h> -#endif -#include <ctype.h> -#include <err.h> -#include <event.h> -#include <fcntl.h> -#include <imsg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "smtpd.h" -#include "log.h" - - -/* db(3) backend */ -static void *map_db_open(struct map *); -static void *map_db_lookup(void *, const char *, enum map_kind); -static int map_db_compare(void *, const char *, enum map_kind, - int (*)(const char *, const char *)); -static void map_db_close(void *); - -static char *map_db_get_entry(void *, const char *, size_t *); -static void *map_db_credentials(const char *, char *, size_t); -static void *map_db_alias(const char *, char *, size_t); -static void *map_db_virtual(const char *, char *, size_t); -static void *map_db_netaddr(const char *, char *, size_t); - - -struct map_backend map_backend_db = { - map_db_open, - NULL, - map_db_close, - map_db_lookup, - map_db_compare -}; - - -static void * -map_db_open(struct map *map) -{ - return dbopen(map->m_config, O_RDONLY, 0600, DB_HASH, NULL); -} - -static void -map_db_close(void *hdl) -{ - DB *db = hdl; - - db->close(db); -} - -static void * -map_db_lookup(void *hdl, const char *key, enum map_kind kind) -{ - char *line; - size_t len; - void *ret; - - line = map_db_get_entry(hdl, key, &len); - if (line == NULL) - return NULL; - - ret = 0; - switch (kind) { - case K_ALIAS: - ret = map_db_alias(key, line, len); - break; - - case K_CREDENTIALS: - ret = map_db_credentials(key, line, len); - break; - - case K_VIRTUAL: - ret = map_db_virtual(key, line, len); - break; - - case K_NETADDR: - ret = map_db_netaddr(key, line, len); - break; - - default: - break; - } - - free(line); - - return ret; -} - -static int -map_db_compare(void *hdl, const char *key, enum map_kind kind, - int (*func)(const char *, const char *)) -{ - int ret = 0; - DB *db = hdl; - DBT dbk; - DBT dbd; - int r; - char *buf = NULL; - - for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r; - r = db->seq(db, &dbk, &dbd, R_NEXT)) { - buf = xmemdup(dbk.data, dbk.size + 1, "map_db_compare"); - log_debug("debug: key: %s, buf: %s", key, buf); - if (func(key, buf)) - ret = 1; - free(buf); - if (ret) - break; - } - return ret; -} - -static char * -map_db_get_entry(void *hdl, const char *key, size_t *len) -{ - int ret; - DBT dbk; - DBT dbv; - DB *db = hdl; - char pkey[MAX_LINE_SIZE]; - - /* workaround the stupidity of the DB interface */ - if (strlcpy(pkey, key, sizeof pkey) >= sizeof pkey) - errx(1, "map_db_get_entry: key too long"); - dbk.data = pkey; - dbk.size = strlen(pkey) + 1; - - if ((ret = db->get(db, &dbk, &dbv, 0)) != 0) - return NULL; - - *len = dbv.size; - - return xmemdup(dbv.data, dbv.size, "map_db_get_entry"); -} - -static void * -map_db_credentials(const char *key, char *line, size_t len) -{ - struct map_credentials *map_credentials = NULL; - char *p; - - /* credentials are stored as user:password */ - if (len < 3) - return NULL; - - /* too big to fit in a smtp session line */ - if (len >= MAX_LINE_SIZE) - return NULL; - - p = strchr(line, ':'); - if (p == NULL) - return NULL; - - if (p == line || p == line + len - 1) - return NULL; - *p++ = '\0'; - - map_credentials = xcalloc(1, sizeof *map_credentials, - "map_db_credentials"); - - if (strlcpy(map_credentials->username, line, - sizeof(map_credentials->username)) >= - sizeof(map_credentials->username)) - goto err; - - if (strlcpy(map_credentials->password, p, - sizeof(map_credentials->password)) >= - sizeof(map_credentials->password)) - goto err; - - return map_credentials; - -err: - free(map_credentials); - return NULL; -} - -static void * -map_db_alias(const char *key, char *line, size_t len) -{ - char *subrcpt; - char *endp; - struct map_alias *map_alias = NULL; - struct expandnode xn; - - map_alias = xcalloc(1, sizeof *map_alias, "map_db_alias"); - - 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'; - - if (! alias_parse(&xn, subrcpt)) - goto error; - - expand_insert(&map_alias->expand, &xn); - map_alias->nbnodes++; - } - - return map_alias; - -error: - expand_free(&map_alias->expand); - free(map_alias); - return NULL; -} - -static void * -map_db_virtual(const char *key, char *line, size_t len) -{ - char *subrcpt; - char *endp; - struct map_virtual *map_virtual = NULL; - struct expandnode xn; - - map_virtual = xcalloc(1, sizeof *map_virtual, "map_db_virtual"); - - /* 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'; - - if (! alias_parse(&xn, subrcpt)) - goto error; - - expand_insert(&map_virtual->expand, &xn); - map_virtual->nbnodes++; - } - - return map_virtual; - -error: - expand_free(&map_virtual->expand); - free(map_virtual); - return NULL; -} - - -static void * -map_db_netaddr(const char *key, char *line, size_t len) -{ - struct map_netaddr *map_netaddr = NULL; - - map_netaddr = xcalloc(1, sizeof *map_netaddr, "map_db_netaddr"); - - if (! text_to_netaddr(&map_netaddr->netaddr, line)) - goto error; - - return map_netaddr; - -error: - free(map_netaddr); - return NULL; -} diff --git a/smtpd/map_file.c b/smtpd/map_file.c deleted file mode 100644 index 2ce6d811..00000000 --- a/smtpd/map_file.c +++ /dev/null @@ -1,179 +0,0 @@ -/* $OpenBSD: map_file.c,v 1.2 2012/11/12 14:58:53 eric Exp $ */ - -/* - * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include <sys/types.h> -#include "sys-queue.h" -#include "sys-tree.h" -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <imsg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "smtpd.h" -#include "log.h" - -/* file backend */ -static void *map_file_open(struct map *); -static void map_file_update(struct map *); -static void *map_file_lookup(void *, const char *, enum map_kind); -static int map_file_compare(void *, const char *, enum map_kind, - int (*)(const char *, const char *)); -static void map_file_close(void *); - -struct map_backend *map_backend_lookup(const char *); - -struct map_backend map_backend_file = { - map_file_open, - map_file_update, - map_file_close, - map_file_lookup, - map_file_compare -}; - -static void -file_load(struct map *m, FILE *fp) -{ - char *buf, *lbuf; - size_t flen; - char *keyp; - char *valp; - - lbuf = NULL; - while ((buf = fgetln(fp, &flen))) { - if (buf[flen - 1] == '\n') - buf[flen - 1] = '\0'; - else { - lbuf = xmalloc(flen + 1, "map_stdio_get_entry"); - memcpy(lbuf, buf, flen); - lbuf[flen] = '\0'; - buf = lbuf; - } - - keyp = buf; - while (isspace((int)*keyp)) - ++keyp; - if (*keyp == '\0' || *keyp == '#') - continue; - valp = keyp; - strsep(&valp, " \t:"); - if (valp) { - while (*valp && isspace(*valp)) - ++valp; - if (*valp == '\0') - valp = NULL; - } - map_add(m, keyp, valp == keyp ? NULL : valp); - } - free(lbuf); -} - - -static void * -map_file_open(struct map *map) -{ - FILE *fp = NULL; - struct map *mp = NULL; - - if (map->m_handle) - return map->m_handle; - - mp = map_create("static", NULL); - - fp = fopen(map->m_config, "r"); - if (fp == NULL) - goto err; - file_load(mp, fp); - fclose(fp); - - map->m_handle = mp; - - log_debug("debug: map_file_open: initialized map \"%s\" from %s", - map->m_name, map->m_config); - - return mp; - -err: - if (mp) - map_destroy(mp); - - if (fp) - fclose(fp); - - return NULL; -} - -static void -map_file_update(struct map *map) -{ - FILE *fp = NULL; - struct map *mp = NULL; - - fp = fopen(map->m_config, "r"); - if (fp == NULL) { - log_warn("warn: Could not update map \"%s\" from %s", - map->m_name, map->m_config); - return; - } - - mp = map_create("static", NULL); - file_load(mp, fp); - fclose(fp); - - if (map->m_handle != NULL) { - map_destroy(map->m_handle); - map->m_handle = NULL; - } - - map->m_handle = mp; - log_info("info: Updated map \"%s\" from %s", map->m_name, map->m_config); -} - -static void -map_file_close(void *hdl) -{ - /* ignore */ -} - -static void * -map_file_lookup(void *hdl, const char *key, enum map_kind kind) -{ - struct map *mp = hdl; - - return map_lookup(mp->m_id, key, kind); -} - -static int -map_file_compare(void *hdl, const char *key, enum map_kind kind, - int (*func)(const char *, const char *)) -{ - struct map *mp = hdl; - - return map_compare(mp->m_id, key, kind, func); -} diff --git a/smtpd/map_static.c b/smtpd/map_static.c deleted file mode 100644 index 2df69cfa..00000000 --- a/smtpd/map_static.c +++ /dev/null @@ -1,276 +0,0 @@ -/* $OpenBSD: map_static.c,v 1.9 2012/11/12 14:58:53 eric Exp $ */ - -/* - * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "includes.h" - -#include <sys/types.h> -#include "sys-queue.h" -#include "sys-tree.h" -#include <sys/param.h> -#include <sys/socket.h> - -#include <ctype.h> -#include <err.h> -#include <event.h> -#include <fcntl.h> -#include <imsg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "smtpd.h" -#include "log.h" - - -/* static backend */ -static void *map_static_open(struct map *); -static void *map_static_lookup(void *, const char *, enum map_kind); -static int map_static_compare(void *, const char *, enum map_kind, - int (*)(const char *, const char *)); -static void map_static_close(void *); - -static void *map_static_credentials(const char *, char *, size_t); -static void *map_static_alias(const char *, char *, size_t); -static void *map_static_virtual(const char *, char *, size_t); -static void *map_static_netaddr(const char *, char *, size_t); - -struct map_backend map_backend_static = { - map_static_open, - NULL, - map_static_close, - map_static_lookup, - map_static_compare -}; - -static void * -map_static_open(struct map *map) -{ - return map; -} - -static void -map_static_close(void *hdl) -{ - return; -} - -static void * -map_static_lookup(void *hdl, const char *key, enum map_kind kind) -{ - struct map *m = hdl; - struct mapel *me = NULL; - char *line; - void *ret; - size_t len; - - line = NULL; - TAILQ_FOREACH(me, &m->m_contents, me_entry) { - if (strcmp(key, me->me_key) == 0) { - if (me->me_val == NULL) - return NULL; - line = strdup(me->me_val); - break; - } - } - - if (line == NULL) - return NULL; - - len = strlen(line); - switch (kind) { - case K_ALIAS: - ret = map_static_alias(key, line, len); - break; - - case K_CREDENTIALS: - ret = map_static_credentials(key, line, len); - break; - - case K_VIRTUAL: - ret = map_static_virtual(key, line, len); - break; - - case K_NETADDR: - ret = map_static_netaddr(key, line, len); - break; - - default: - ret = NULL; - break; - } - - free(line); - - return ret; -} - -static int -map_static_compare(void *hdl, const char *key, enum map_kind kind, - int (*func)(const char *, const char *)) -{ - struct map *m = hdl; - struct mapel *me = NULL; - int ret = 0; - - TAILQ_FOREACH(me, &m->m_contents, me_entry) { - if (! func(key, me->me_key)) - continue; - ret = 1; - break; - } - - return ret; -} - -static void * -map_static_credentials(const char *key, char *line, size_t len) -{ - struct map_credentials *map_credentials = NULL; - char *p; - - /* credentials are stored as user:password */ - if (len < 3) - return NULL; - - /* too big to fit in a smtp session line */ - if (len >= MAX_LINE_SIZE) - return NULL; - - p = strchr(line, ':'); - if (p == NULL) - return NULL; - - if (p == line || p == line + len - 1) - return NULL; - *p++ = '\0'; - - map_credentials = xcalloc(1, sizeof *map_credentials, - "map_static_credentials"); - - if (strlcpy(map_credentials->username, line, - sizeof(map_credentials->username)) >= - sizeof(map_credentials->username)) - goto err; - - if (strlcpy(map_credentials->password, p, - sizeof(map_credentials->password)) >= - sizeof(map_credentials->password)) - goto err; - - return map_credentials; - -err: - free(map_credentials); - return NULL; -} - -static void * -map_static_alias(const char *key, char *line, size_t len) -{ - char *subrcpt; - char *endp; - struct map_alias *map_alias = NULL; - struct expandnode xn; - - map_alias = xcalloc(1, sizeof *map_alias, "map_static_alias"); - - 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'; - - if (! alias_parse(&xn, subrcpt)) - goto error; - - expand_insert(&map_alias->expand, &xn); - map_alias->nbnodes++; - } - - return map_alias; - -error: - expand_free(&map_alias->expand); - free(map_alias); - return NULL; -} - -static void * -map_static_virtual(const char *key, char *line, size_t len) -{ - char *subrcpt; - char *endp; - struct map_virtual *map_virtual = NULL; - struct expandnode xn; - - map_virtual = xcalloc(1, sizeof *map_virtual, "map_static_virtual"); - - /* 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'; - - if (! alias_parse(&xn, subrcpt)) - goto error; - - expand_insert(&map_virtual->expand, &xn); - map_virtual->nbnodes++; - } - - return map_virtual; - -error: - expand_free(&map_virtual->expand); - free(map_virtual); - return NULL; -} - - -static void * -map_static_netaddr(const char *key, char *line, size_t len) -{ - struct map_netaddr *map_netaddr = NULL; - - map_netaddr = xcalloc(1, sizeof *map_netaddr, "map_static_netaddr"); - - if (! text_to_netaddr(&map_netaddr->netaddr, line)) - goto error; - - return map_netaddr; - -error: - free(map_netaddr); - return NULL; -} diff --git a/smtpd/mda.c b/smtpd/mda.c index 83a4995f..e38f4eec 100644 --- a/smtpd/mda.c +++ b/smtpd/mda.c @@ -131,8 +131,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) if (!strcmp(name, u->name)) break; if (u && u->evpcount >= MDA_MAXEVPUSER) { - log_debug("debug: mda: too many envelopes for \"%s\"", - u->name); + log_debug("debug: mda: too many envelopes for " + "\"%s\"", u->name); envelope_set_errormsg(ep, "User envelope limit reached"); imsg_compose_event(env->sc_ievs[PROC_QUEUE], @@ -148,8 +148,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) TAILQ_INSERT_TAIL(&users, u, entry); } if (u->runnable == 0 && u->running < MDA_MAXSESSUSER) { - log_debug("debug: mda: \"%s\" immediatly runnable", - u->name); + log_debug("debug: mda: \"%s\" immediatly " + "runnable", u->name); TAILQ_INSERT_TAIL(&runnable, u, entry_runnable); u->runnable = 1; } @@ -203,7 +203,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) s->evp->rcpt.user, s->evp->rcpt.domain); if (n == -1) { - log_warn("warn: mda: fail to write delivery info"); + log_warn("warn: mda: " + "fail to write delivery info"); envelope_set_errormsg(s->evp, "Out of memory"); mda_done(s, IMSG_QUEUE_DELIVERY_TEMPFAIL); return; @@ -216,17 +217,17 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) case A_MDA: deliver.mode = A_MDA; strlcpy(deliver.user, d_mda->user.username, - sizeof (deliver.user)); + sizeof(deliver.user)); strlcpy(deliver.to, d_mda->buffer, - sizeof deliver.to); + sizeof(deliver.to)); break; - + case A_MBOX: deliver.mode = A_MBOX; strlcpy(deliver.user, "root", - sizeof (deliver.user)); + sizeof(deliver.user)); strlcpy(deliver.to, d_mda->user.username, - sizeof (deliver.to)); + sizeof(deliver.to)); snprintf(deliver.from, sizeof(deliver.from), "%s@%s", ep->sender.user, ep->sender.domain); @@ -235,9 +236,9 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) case A_MAILDIR: deliver.mode = A_MAILDIR; strlcpy(deliver.user, d_mda->user.username, - sizeof deliver.user); + sizeof(deliver.user)); strlcpy(deliver.to, d_mda->buffer, - sizeof deliver.to); + sizeof(deliver.to)); break; case A_FILENAME: @@ -284,7 +285,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) */ output[0] = '\0'; if (imsg->fd != -1) - mda_getlastline(imsg->fd, output, sizeof output); + mda_getlastline(imsg->fd, output, + sizeof output); /* * Choose between parent's description of error and @@ -304,7 +306,8 @@ mda_imsg(struct imsgev *iev, struct imsg *imsg) if (error) { msg = IMSG_QUEUE_DELIVERY_TEMPFAIL; envelope_set_errormsg(s->evp, "%s", error); - snprintf(stat, sizeof stat, "Error (%s)", error); + snprintf(stat, sizeof stat, "Error (%s)", + error); } log_envelope(s->evp, NULL, error ? "TempFail" : "Ok", error ? stat : "Delivered"); @@ -420,10 +423,10 @@ mda_io(struct io *io, int evt) char *ln, buf[256]; size_t len; - log_trace(TRACE_IO, "mda: %p: %s %s", s, io_strevent(evt), io_strio(io)); - - switch(evt) { + log_trace(TRACE_IO, "mda: %p: %s %s", s, io_strevent(evt), + io_strio(io)); + switch (evt) { case IO_LOWAT: /* done */ @@ -578,11 +581,13 @@ mda_drain(void) while ((user = (TAILQ_FIRST(&runnable)))) { if (running >= MDA_MAXSESS) { - log_debug("debug: mda: maximum number of session reached"); + log_debug("debug: mda: " + "maximum number of session reached"); return; } - log_debug("debug: mda: new session for user \"%s\"", user->name); + log_debug("debug: mda: new session for user \"%s\"", + user->name); s = xcalloc(1, sizeof *s, "mda_drain"); s->user = user; @@ -618,7 +623,8 @@ mda_drain(void) user->running < MDA_MAXSESSUSER) { TAILQ_INSERT_TAIL(&runnable, user, entry_runnable); user->runnable = 1; - log_debug("debug: mda: user \"%s\" still runnable", user->name); + log_debug("debug: mda: user \"%s\" still runnable", + user->name); } } } @@ -637,16 +643,17 @@ mda_done(struct mda_session *s, int msg) stat_decrement("mda.running", 1); if (TAILQ_FIRST(&s->user->envelopes) == NULL && s->user->running == 0) { - log_debug("debug: mda: all done for user \"%s\"", s->user->name); + log_debug("debug: mda: " + "all done for user \"%s\"", s->user->name); TAILQ_REMOVE(&users, s->user, entry); free(s->user); } else if (s->user->runnable == 0 && - TAILQ_FIRST(&s->user->envelopes) && - s->user->running < MDA_MAXSESSUSER) { - log_debug("debug: mda: user \"%s\" becomes runnable", - s->user->name); - TAILQ_INSERT_TAIL(&runnable, s->user, entry_runnable); - s->user->runnable = 1; + TAILQ_FIRST(&s->user->envelopes) && + s->user->running < MDA_MAXSESSUSER) { + log_debug("debug: mda: user \"%s\" becomes runnable", + s->user->name); + TAILQ_INSERT_TAIL(&runnable, s->user, entry_runnable); + s->user->runnable = 1; } if (s->datafp) diff --git a/smtpd/mfa.c b/smtpd/mfa.c index 297a06b5..e42cdc7e 100644 --- a/smtpd/mfa.c +++ b/smtpd/mfa.c @@ -118,13 +118,15 @@ mfa_imsg(struct imsgev *iev, struct imsg *imsg) return; case IMSG_CONF_FILTER: - filter = xmemdup(imsg->data, sizeof *filter, "mfa_imsg"); + filter = xmemdup(imsg->data, sizeof *filter, + "mfa_imsg"); TAILQ_INSERT_TAIL(env->sc_filters, filter, f_entry); return; case IMSG_CONF_END: TAILQ_FOREACH(filter, env->sc_filters, f_entry) { - log_info("info: Forking filter: %s", filter->name); + log_info("info: Forking filter: %s", + filter->name); if (! mfa_fork_filter(filter)) fatalx("could not fork filter"); } @@ -302,7 +304,8 @@ mfa_test_mail(struct envelope *e) /* * "MAIL FROM:<>" is the exception we allow. */ - if (!(ss.u.maddr.user[0] == '\0' && ss.u.maddr.domain[0] == '\0')) + if (!(ss.u.maddr.user[0] == '\0' && + ss.u.maddr.domain[0] == '\0')) goto refuse; } @@ -310,8 +313,8 @@ mfa_test_mail(struct envelope *e) return; refuse: - imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_MAIL, 0, 0, -1, &ss, - sizeof(ss)); + imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_MAIL, 0, 0, -1, + &ss, sizeof(ss)); return; } @@ -333,7 +336,7 @@ mfa_test_rcpt(struct envelope *e) ss.flags = e->flags; mfa_strip_source_route(ss.u.maddr.user, sizeof(ss.u.maddr.user)); - + if (! valid_localpart(ss.u.maddr.user) || ! valid_domainpart(ss.u.maddr.domain)) goto refuse; @@ -342,16 +345,16 @@ mfa_test_rcpt(struct envelope *e) return; refuse: - imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_RCPT, 0, 0, -1, &ss, - sizeof(ss)); + imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_RCPT, 0, 0, -1, + &ss, sizeof(ss)); } static void mfa_test_rcpt_resume(struct submit_status *ss) { if (ss->code != 250) { - imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_RCPT, 0, 0, -1, ss, - sizeof(*ss)); + imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_MFA_RCPT, 0, 0, + -1, ss, sizeof(*ss)); return; } @@ -442,7 +445,7 @@ mfa_fork_filter(struct filter *filter) if (pid == 0) { /* filter */ dup2(sockpair[0], STDIN_FILENO); - + closefrom(STDERR_FILENO + 1); execl(filter->path, filter->name, NULL); diff --git a/smtpd/mfa_session.c b/smtpd/mfa_session.c index db079ab4..36fb8fc8 100644 --- a/smtpd/mfa_session.c +++ b/smtpd/mfa_session.c @@ -73,7 +73,7 @@ mfa_session(struct submit_status *ss, enum session_state state) static int mfa_session_proceed(struct mfa_session *ms) { - struct filter_msg fm; + struct filter_msg fm; fm.id = ms->id; fm.cl_id = ms->ss.id; @@ -84,15 +84,17 @@ mfa_session_proceed(struct mfa_session *ms) case S_CONNECTED: fm.type = FILTER_CONNECT; if (strlcpy(fm.u.connect.hostname, ms->ss.envelope.hostname, - sizeof(fm.u.connect.hostname)) >= sizeof(fm.u.connect.hostname)) + sizeof(fm.u.connect.hostname)) + >= sizeof(fm.u.connect.hostname)) fatalx("mfa_session_proceed: CONNECT: truncation"); fm.u.connect.hostaddr = ms->ss.envelope.ss; break; - case S_HELO: + case S_HELO: fm.type = FILTER_HELO; if (strlcpy(fm.u.helo.helohost, ms->ss.envelope.helo, - sizeof(fm.u.helo.helohost)) >= sizeof(fm.u.helo.helohost)) + sizeof(fm.u.helo.helohost)) + >= sizeof(fm.u.helo.helohost)) fatalx("mfa_session_proceed: HELO: truncation"); break; @@ -119,7 +121,8 @@ mfa_session_proceed(struct mfa_session *ms) case S_DATACONTENT: fm.type = FILTER_DATALINE; if (strlcpy(fm.u.dataline.line, ms->ss.u.dataline, - sizeof(fm.u.dataline.line)) >= sizeof(fm.u.dataline.line)) + sizeof(fm.u.dataline.line)) + >= sizeof(fm.u.dataline.line)) fatalx("mfa_session_proceed: DATA: line truncation"); break; @@ -141,7 +144,8 @@ mfa_session_proceed(struct mfa_session *ms) imsg_compose(ms->filter->ibuf, fm.type, 0, 0, -1, &fm, sizeof(fm)); - event_set(&ms->filter->ev, ms->filter->ibuf->fd, EV_READ|EV_WRITE, mfa_session_imsg, ms->filter); + event_set(&ms->filter->ev, ms->filter->ibuf->fd, EV_READ|EV_WRITE, + mfa_session_imsg, ms->filter); event_add(&ms->filter->ev, NULL); return 1; } @@ -175,8 +179,9 @@ mfa_session_done(struct mfa_session *ms) break; case S_MAIL_MFA: if (ms->ss.code != 530) { - imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_MAIL, 0, - 0, -1, &ms->ss, sizeof(ms->ss)); + imsg_compose_event(env->sc_ievs[PROC_LKA], + IMSG_LKA_MAIL, 0, 0, -1, + &ms->ss, sizeof(ms->ss)); mfa_session_destroy(ms); return; } @@ -184,8 +189,9 @@ mfa_session_done(struct mfa_session *ms) break; case S_RCPT_MFA: if (ms->ss.code != 530) { - imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_RULEMATCH, - 0, 0, -1, &ms->ss, sizeof(ms->ss)); + imsg_compose_event(env->sc_ievs[PROC_LKA], + IMSG_LKA_RULEMATCH, 0, 0, -1, + &ms->ss, sizeof(ms->ss)); mfa_session_destroy(ms); return; } @@ -193,8 +199,9 @@ mfa_session_done(struct mfa_session *ms) break; case S_DATACONTENT: if (ms->ss.code != 530 && ms->fm.code != 0) - (void)strlcpy(ms->ss.u.dataline, ms->fm.u.dataline.line, - sizeof(ms->ss.u.dataline)); + (void)strlcpy(ms->ss.u.dataline, + ms->fm.u.dataline.line, + sizeof(ms->ss.u.dataline)); imsg_type = IMSG_MFA_DATALINE; break; case S_QUIT: diff --git a/smtpd/mta.c b/smtpd/mta.c index b0121a2b..69c21d75 100644 --- a/smtpd/mta.c +++ b/smtpd/mta.c @@ -64,7 +64,8 @@ static void mta_sig_handler(int, short, void *); static struct mta_route *mta_route_for(struct envelope *); static void mta_route_drain(struct mta_route *); static void mta_route_free(struct mta_route *); -static void mta_envelope_done(struct mta_task *, struct envelope *, const char *); +static void mta_envelope_done(struct mta_task *, struct envelope *, + const char *); static int mta_route_cmp(struct mta_route *, struct mta_route *); SPLAY_PROTOTYPE(mta_route_tree, mta_route, entry, mta_route_cmp); @@ -100,7 +101,8 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg) route = mta_route_for(e); batch = tree_xget(&batches, e->batch_id); - if ((task = tree_get(&batch->tasks, route->id)) == NULL) { + if ((task = tree_get(&batch->tasks, route->id)) + == NULL) { log_trace(TRACE_MTA, "mta: new task for %s", mta_route_to_text(route)); task = xmalloc(sizeof *task, "mta_task"); @@ -122,7 +124,8 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg) /* XXX honour route->maxrcpt */ TAILQ_INSERT_TAIL(&task->envelopes, e, entry); stat_increment("mta.envelope", 1); - log_debug("debug: mta: received evp:%016" PRIx64 " for <%s@%s>", + log_debug("debug: mta: received evp:%016" PRIx64 + " for <%s@%s>", e->id, e->dest.user, e->dest.domain); return; @@ -132,12 +135,14 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg) log_trace(TRACE_MTA, "mta: batch:%016" PRIx64 " closed", batch->id); /* for all tasks, queue them on there route */ - while (tree_poproot(&batch->tasks, &id, (void**)&task)) { + while (tree_poproot(&batch->tasks, &id, + (void**)&task)) { if (id != task->route->id) errx(1, "route id mismatch!"); task->route->refcount -= 1; task->route->ntask += 1; - TAILQ_INSERT_TAIL(&task->route->tasks, task, entry); + TAILQ_INSERT_TAIL(&task->route->tasks, task, + entry); stat_increment("mta.task", 1); mta_route_drain(task->route); } @@ -167,7 +172,8 @@ mta_imsg(struct imsgev *iev, struct imsg *imsg) if (env->sc_flags & SMTPD_CONFIGURING) return; env->sc_flags |= SMTPD_CONFIGURING; - env->sc_ssl = xcalloc(1, sizeof *env->sc_ssl, "mta:sc_ssl"); + env->sc_ssl = xcalloc(1, sizeof *env->sc_ssl, + "mta:sc_ssl"); return; case IMSG_CONF_SSL: @@ -438,7 +444,7 @@ mta_route_for(struct envelope *e) key.cert = e->agent.mta.relay.cert; if (!key.cert[0]) key.cert = NULL; - key.auth = e->agent.mta.relay.authmap; + key.auth = e->agent.mta.relay.authtable; if (!key.auth[0]) key.auth = NULL; @@ -454,7 +460,8 @@ mta_route_for(struct envelope *e) route->cert = key.cert ? xstrdup(key.cert, "mta: cert") : NULL; route->auth = key.auth ? xstrdup(key.auth, "mta: auth") : NULL; if (route->cert) { - strlcpy(ssl.ssl_name, route->cert, sizeof(ssl.ssl_name)); + strlcpy(ssl.ssl_name, route->cert, + sizeof(ssl.ssl_name)); route->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &ssl); } SPLAY_INSERT(mta_route_tree, &routes, route); @@ -466,7 +473,8 @@ mta_route_for(struct envelope *e) log_trace(TRACE_MTA, "mta: new %s", mta_route_to_text(route)); stat_increment("mta.route", 1); } else { - log_trace(TRACE_MTA, "mta: reusing %s", mta_route_to_text(route)); + log_trace(TRACE_MTA, "mta: reusing %s", + mta_route_to_text(route)); } return (route); @@ -502,7 +510,8 @@ mta_route_drain(struct mta_route *route) } if (route->ntask == 0) { - log_debug("debug: mta: no task for %s", mta_route_to_text(route)); + log_debug("debug: mta: no task for %s", + mta_route_to_text(route)); return; } @@ -516,7 +525,7 @@ mta_route_drain(struct mta_route *route) while ((task = TAILQ_FIRST(&route->tasks))) { TAILQ_REMOVE(&route->tasks, task, entry); route->ntask -= 1; - while((e = TAILQ_FIRST(&task->envelopes))) + while ((e = TAILQ_FIRST(&task->envelopes))) mta_envelope_done(task, e, route->errorline); free(task); stat_decrement("mta.task", 1); diff --git a/smtpd/mta_session.c b/smtpd/mta_session.c index 25681189..95bab2a8 100644 --- a/smtpd/mta_session.c +++ b/smtpd/mta_session.c @@ -111,7 +111,8 @@ struct mta_session { static void mta_io(struct io *, int); static void mta_enter_state(struct mta_session *, int); static void mta_status(struct mta_session *, int, const char *, ...); -static void mta_envelope_done(struct mta_task *, struct envelope *, const char *); +static void mta_envelope_done(struct mta_task *, struct envelope *, + const char *); static void mta_send(struct mta_session *, char *, ...); static ssize_t mta_queue_data(struct mta_session *); static void mta_response(struct mta_session *, char *); @@ -153,7 +154,8 @@ mta_session(struct mta_route *route) session->flags |= MTA_ALLOW_PLAIN; } - log_debug("debug: mta: %p: spawned for %s", session, mta_route_to_text(route)); + log_debug("debug: mta: %p: spawned for %s", session, + mta_route_to_text(route)); stat_increment("mta.session", 1); mta_enter_state(session, MTA_INIT); } @@ -169,8 +171,7 @@ mta_session_imsg(struct imsgev *iev, struct imsg *imsg) const char *error; void *ptr; - switch(imsg->hdr.type) { - + switch (imsg->hdr.type) { case IMSG_QUEUE_MESSAGE_FD: id = *(uint64_t*)(imsg->data); if (imsg->fd == -1) @@ -247,7 +248,8 @@ mta_session_imsg(struct imsgev *iev, struct imsg *imsg) /* check if we need to start tls now... */ if (((s->flags & MTA_FORCE_ANYSSL) && host->used == 1) || (s->flags & MTA_FORCE_SMTPS)) { - log_debug("debug: mta: %p: trying smtps (ssl=%p)...", s, s->ssl); + log_debug("debug: mta: %p: trying smtps (ssl=%p)...", + s, s->ssl); if ((ptr = ssl_mta_init(s->ssl)) == NULL) fatalx("mta: ssl_mta_init"); io_start_tls(&s->io, ptr); @@ -311,10 +313,11 @@ mta_enter_state(struct mta_session *s, int newstate) */ bzero(&secret, sizeof(secret)); secret.id = s->id; - strlcpy(secret.mapname, s->route->auth, sizeof(secret.mapname)); + strlcpy(secret.tablename, s->route->auth, + sizeof(secret.tablename)); strlcpy(secret.host, s->route->hostname, sizeof(secret.host)); imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_LKA_SECRET, - 0, 0, -1, &secret, sizeof(secret)); + 0, 0, -1, &secret, sizeof(secret)); break; case MTA_MX: @@ -322,16 +325,18 @@ mta_enter_state(struct mta_session *s, int newstate) * Lookup MX record. */ if (s->flags & MTA_FORCE_MX) /* XXX */ - dns_query_host(s->route->hostname, s->route->port, s->id); + dns_query_host(s->route->hostname, s->route->port, + s->id); else - dns_query_mx(s->route->hostname, s->route->backupname, 0, s->id); + dns_query_mx(s->route->hostname, s->route->backupname, + 0, s->id); break; case MTA_CONNECT: /* * Connect to the MX. */ - + /* cleanup previous connection if any */ iobuf_clear(&s->iobuf); io_clear(&s->io); @@ -356,7 +361,8 @@ mta_enter_state(struct mta_session *s, int newstate) if (s->route->port) sa_set_port(sa, s->route->port); - else if ((s->flags & MTA_FORCE_ANYSSL) && host->used == 1) + else if ((s->flags & MTA_FORCE_ANYSSL) && + host->used == 1) sa_set_port(sa, 465); else if (s->flags & MTA_FORCE_SMTPS) sa_set_port(sa, 465); @@ -367,7 +373,8 @@ mta_enter_state(struct mta_session *s, int newstate) io_init(&s->io, -1, s, mta_io, &s->iobuf); io_set_timeout(&s->io, 10000); if (io_connect(&s->io, sa, NULL) == -1) { - log_debug("debug: mta: %p: connection failed: %s", s, + log_debug("debug: mta: %p: " + "connection failed: %s", s, strerror(errno)); iobuf_clear(&s->iobuf); /* @@ -438,8 +445,8 @@ mta_enter_state(struct mta_session *s, int newstate) if (s->secret && s->flags & MTA_TLS) mta_send(s, "AUTH PLAIN %s", s->secret); else if (s->secret) { - log_debug("debug: mta: %p: not using AUTH on non-TLS session", - s); + log_debug("debug: mta: " + "%p: not using AUTH on non-TLS session", s); mta_enter_state(s, MTA_CONNECT); } else { mta_enter_state(s, MTA_SMTP_READY); @@ -453,11 +460,13 @@ mta_enter_state(struct mta_session *s, int newstate) mta_route_ok(s->route); } if (s->msgcount >= s->route->maxmail) { - log_debug("debug: mta: %p: cannot send more message to %s", s, + log_debug("debug: mta: " + "%p: cannot send more message to %s", s, mta_route_to_text(s->route)); mta_enter_state(s, MTA_SMTP_QUIT); } else if ((s->task = TAILQ_FIRST(&s->route->tasks))) { - log_debug("debug: mta: %p: handling next task for %s", s, + log_debug("debug: mta: " + "%p: handling next task for %s", s, mta_route_to_text(s->route)); TAILQ_REMOVE(&s->route->tasks, s->task, entry); s->route->ntask -= 1; @@ -654,7 +663,8 @@ mta_io(struct io *io, int evt) const char *error; int cont; - log_trace(TRACE_IO, "mta: %p: %s %s", s, io_strevent(evt), io_strio(io)); + log_trace(TRACE_IO, "mta: %p: %s %s", s, io_strevent(evt), + io_strio(io)); switch (evt) { @@ -714,7 +724,7 @@ mta_io(struct io *io, int evt) io_set_write(io); mta_response(s, line); - iobuf_normalize(&s->iobuf); + iobuf_normalize(&s->iobuf); if (iobuf_len(&s->iobuf)) { log_debug("debug: mta: remaining data in input buffer"); @@ -752,7 +762,8 @@ mta_io(struct io *io, int evt) break; case IO_DISCONNECTED: - log_debug("debug: mta: %p: disconnected in state %s", s, mta_strstate(s->state)); + log_debug("debug: mta: %p: disconnected in state %s", + s, mta_strstate(s->state)); if (!s->ready) { mta_enter_state(s, MTA_CONNECT); break; @@ -831,7 +842,7 @@ mta_status(struct mta_session *s, int connerr, const char *fmt, ...) va_end(ap); if (s->task) { - while((e = TAILQ_FIRST(&s->task->envelopes))) + while ((e = TAILQ_FIRST(&s->task->envelopes))) mta_envelope_done(s->task, e, status); free(s->task); s->task = NULL; @@ -881,7 +892,7 @@ mta_strstate(int state) CASE(MTA_CONNECT); CASE(MTA_DONE); CASE(MTA_SMTP_READY); - CASE(MTA_SMTP_BANNER); + CASE(MTA_SMTP_BANNER); CASE(MTA_SMTP_EHLO); CASE(MTA_SMTP_HELO); CASE(MTA_SMTP_STARTTLS); diff --git a/smtpd/parse.y b/smtpd/parse.y index ea4881dd..4e423832 100644 --- a/smtpd/parse.y +++ b/smtpd/parse.y @@ -94,7 +94,7 @@ char *symget(const char *); struct smtpd *conf = NULL; static int errors = 0; -struct map *map = NULL; +struct table *table = NULL; struct rule *rule = NULL; TAILQ_HEAD(condlist, cond) *conditions = NULL; @@ -132,7 +132,7 @@ typedef struct { %token AUTH_OPTIONAL TLS_REQUIRE %token <v.string> STRING %token <v.number> NUMBER -%type <v.map> table +%type <v.table> table %type <v.number> port from auth ssl size expire %type <v.cond> condition %type <v.object> tables tablenew tableref alias credentials @@ -273,13 +273,13 @@ expire : EXPIRE STRING { ; credentials : AUTH tables { - struct map *m; + struct table *m; /* AUTH only accepts T_DYNAMIC and T_HASH */ - m = map_find($2); - if (!(m->m_type & (T_DYNAMIC|T_HASH))) { + m = table_find($2); + if (!(m->t_type & (T_DYNAMIC|T_HASH))) { yyerror("table \"%s\" can't be used as AUTH parameter", - m->m_name); + m->t_name); YYERROR; } $$ = $2; @@ -425,11 +425,12 @@ table : TABLE STRING STRING { p = $3; if (*p == '/') { - backend = "file"; - config = $3; + backend = "static"; + config = $3; } else { - p = backend = config = NULL; + backend = $3; + config = NULL; for (p = $3; *p && *p != ':'; p++) ; if (*p == ':') { @@ -438,31 +439,28 @@ table : TABLE STRING STRING { config = p+1; } } - if (config == NULL || *config != '/') { - yyerror("table parameter must be absolute path"); + if (config != NULL && *config != '/') { + yyerror("backend parameter must be an absolute path"); free($2); free($3); YYERROR; } - - map = map_create(backend, $2); - if (strlcpy(map->m_config, config, sizeof(map->m_config)) - >= sizeof(map->m_config)) - err(1, "pathname too long"); + table = table_create(backend, $2, config); + table->t_backend->config(table, config); free($2); free($3); } | TABLE STRING { - map = map_create("static", $2); + table = table_create("static", $2, NULL); free($2); } '{' tableval_list '}' { - map = NULL; + table = NULL; } ; keyval : STRING ARROW STRING { - map->m_type = T_HASH; - map_add(map, $1, $3); + table->t_type = T_HASH; + table_add(table, $1, $3); free($1); free($3); } @@ -473,8 +471,8 @@ keyval_list : keyval ; stringel : STRING { - map->m_type = T_LIST; - map_add(map, $1, NULL); + table->t_type = T_LIST; + table_add(table, $1, NULL); free($1); } ; @@ -488,30 +486,30 @@ tableval_list : string_list { } ; tablenew : STRING { - struct map *m; + struct table *m; - m = map_create("static", NULL); - m->m_type = T_LIST; - map_add(m, $1, NULL); - $$ = m->m_id; + m = table_create("static", NULL, NULL); + m->t_type = T_LIST; + table_add(m, $1, NULL); + $$ = m->t_id; } | '{' { - map = map_create("static", NULL); + table = table_create("static", NULL, NULL); } tableval_list '}' { - $$ = map->m_id; + $$ = table->t_id; } ; tableref : '<' STRING '>' { - struct map *m; + struct table *m; - if ((m = map_findbyname($2)) == NULL) { + if ((m = table_findbyname($2)) == NULL) { yyerror("no such table: %s", $2); free($2); YYERROR; } free($2); - $$ = m->m_id; + $$ = m->t_id; } ; @@ -520,59 +518,59 @@ tables : tablenew { $$ = $1; } ; alias : ALIAS tables { - struct map *m; + struct table *m; /* ALIAS only accepts T_DYNAMIC and T_HASH */ - m = map_find($2); - if (!(m->m_type & (T_DYNAMIC|T_HASH))) { + m = table_find($2); + if (!(m->t_type & (T_DYNAMIC|T_HASH))) { yyerror("table \"%s\" can't be used as ALIAS parameter", - m->m_name); + m->t_name); YYERROR; } - $$ = m->m_id; + $$ = m->t_id; } | /* empty */ { $$ = 0; } ; condition : DOMAIN tables alias { struct cond *c; - struct map *m; + struct table *m; /* DOMAIN only accepts T_DYNAMIC and T_LIST */ - m = map_find($2); - if (!(m->m_type & (T_DYNAMIC|T_LIST))) { + m = table_find($2); + if (!(m->t_type & (T_DYNAMIC|T_LIST))) { yyerror("table \"%s\" can't be used as DOMAIN parameter", - m->m_name); + m->t_name); YYERROR; } - rule->r_amap = $3; + rule->r_atable = $3; c = xcalloc(1, sizeof *c, "parse condition: DOMAIN"); c->c_type = COND_DOM; - c->c_map = $2; + c->c_table = $2; $$ = c; } | VIRTUAL tables { struct cond *c; - struct map *m; + struct table *m; /* VIRTUAL only accepts T_DYNAMIC and T_LIST */ - m = map_find($2); - if (!(m->m_type & (T_DYNAMIC|T_HASH))) { + m = table_find($2); + if (!(m->t_type & (T_DYNAMIC|T_HASH))) { yyerror("table \"%s\" can't be used as VIRTUAL parameter", - m->m_name); + m->t_name); YYERROR; } c = xcalloc(1, sizeof *c, "parse condition: VIRTUAL"); c->c_type = COND_VDOM; - c->c_map = $2; + c->c_table = $2; $$ = c; } | LOCAL alias { struct cond *c; - struct map *m; + struct table *m; char hostname[MAXHOSTNAMELEN]; if (gethostname(hostname, sizeof hostname) == -1) { @@ -580,15 +578,15 @@ condition : DOMAIN tables alias { YYERROR; } - rule->r_amap = $2; + rule->r_atable = $2; - m = map_create("static", NULL); - map_add(m, "localhost", NULL); - map_add(m, hostname, NULL); + m = table_create("static", NULL, NULL); + table_add(m, "localhost", NULL); + table_add(m, hostname, NULL); c = xcalloc(1, sizeof *c, "parse condition: LOCAL"); c->c_type = COND_DOM; - c->c_map = m->m_id; + c->c_table = m->t_id; $$ = c; } @@ -598,7 +596,7 @@ condition : DOMAIN tables alias { c = xcalloc(1, sizeof *c, "parse condition: ANY"); c->c_type = COND_ANY; - rule->r_amap = $2; + rule->r_atable = $2; $$ = c; } ; @@ -727,7 +725,7 @@ action : DELIVER TO MAILDIR { free($3); } | RELAY VIA STRING certname credentials relay_as { - struct map *m; + struct table *m; rule->r_action = A_RELAYVIA; rule->r_as = $6; @@ -749,9 +747,9 @@ action : DELIVER TO MAILDIR { free($6); YYERROR; } - m = map_find($5); - strlcpy(rule->r_value.relayhost.authmap, m->m_name, - sizeof(rule->r_value.relayhost.authmap)); + m = table_find($5); + strlcpy(rule->r_value.relayhost.authtable, m->t_name, + sizeof(rule->r_value.relayhost.authtable)); } if ($4 != NULL) { @@ -772,26 +770,26 @@ action : DELIVER TO MAILDIR { ; from : FROM tables { - struct map *m; + struct table *m; /* FROM only accepts T_DYNAMIC and T_LIST */ - m = map_find($2); - if (!(m->m_type & (T_DYNAMIC|T_LIST))) { + m = table_find($2); + if (!(m->t_type & (T_DYNAMIC|T_LIST))) { yyerror("table \"%s\" can't be used as FROM parameter", - m->m_name); + m->t_name); YYERROR; } $$ = $2; } | FROM ANY { - $$ = map_findbyname("<anyhost>")->m_id; + $$ = table_findbyname("<anyhost>")->t_id; } | FROM LOCAL { - $$ = map_findbyname("<localhost>")->m_id; + $$ = table_findbyname("<localhost>")->t_id; } | /* empty */ { - $$ = map_findbyname("<localhost>")->m_id; + $$ = table_findbyname("<localhost>")->t_id; } ; @@ -811,7 +809,7 @@ rule : ACCEPT on from { rule = xcalloc(1, sizeof(*rule), "parse rule: ACCEPT"); rule->r_decision = R_ACCEPT; - rule->r_sources = map_find($3); + rule->r_sources = table_find($3); conditions = xcalloc(1, sizeof(*conditions), "parse rule: ACCEPT"); @@ -844,7 +842,7 @@ rule : ACCEPT on from { free(cond); } - if (rule->r_amap) { + if (rule->r_atable) { if (rule->r_action == A_RELAY || rule->r_action == A_RELAYVIA) { yyerror("aliases set on a relay rule"); @@ -863,7 +861,7 @@ rule : ACCEPT on from { rule = xcalloc(1, sizeof(*rule), "parse rule: REJECT"); rule->r_decision = R_REJECT; - rule->r_sources = map_find($3); + rule->r_sources = table_find($3); conditions = xcalloc(1, sizeof(*conditions), "parse rule: REJECT"); @@ -1299,19 +1297,19 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) conf->sc_maxsize = DEFAULT_MAX_BODY_SIZE; - conf->sc_maps = calloc(1, sizeof(*conf->sc_maps)); + conf->sc_tables = calloc(1, sizeof(*conf->sc_tables)); conf->sc_rules = calloc(1, sizeof(*conf->sc_rules)); 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)); - if (conf->sc_maps == NULL || + if (conf->sc_tables == NULL || conf->sc_rules == NULL || conf->sc_listeners == NULL || conf->sc_ssl == NULL || conf->sc_filters == NULL) { log_warn("warn: cannot allocate memory"); - free(conf->sc_maps); + free(conf->sc_tables); free(conf->sc_rules); free(conf->sc_listeners); free(conf->sc_ssl); @@ -1321,11 +1319,11 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) errors = 0; - map = NULL; + table = NULL; rule = NULL; TAILQ_INIT(conf->sc_listeners); - TAILQ_INIT(conf->sc_maps); + TAILQ_INIT(conf->sc_tables); TAILQ_INIT(conf->sc_rules); TAILQ_INIT(conf->sc_filters); SPLAY_INIT(conf->sc_ssl); @@ -1341,7 +1339,7 @@ parse_config(struct smtpd *x_conf, const char *filename, int opts) topfile = file; /* - * declare special "localhost" and "anyhost" maps + * declare special "localhost" and "anyhost" tables */ set_localaddrs(); @@ -1677,12 +1675,12 @@ set_localaddrs(void) struct sockaddr_storage ss; struct sockaddr_in *sain; struct sockaddr_in6 *sin6; - struct map *m; + struct table *m; - m = map_create("static", "<anyhost>"); - map_add(m, "local", NULL); - map_add(m, "0.0.0.0/0", NULL); - map_add(m, "::/0", NULL); + m = table_create("static", "<anyhost>", NULL); + table_add(m, "local", NULL); + table_add(m, "0.0.0.0/0", NULL); + table_add(m, "::/0", NULL); #ifdef VALGRIND bzero(&ss, sizeof(ss)); @@ -1691,8 +1689,8 @@ set_localaddrs(void) if (getifaddrs(&ifap) == -1) fatal("getifaddrs"); - m = map_create("static", "<localhost>"); - map_add(m, "local", NULL); + m = table_create("static", "<localhost>", NULL); + table_add(m, "local", NULL); for (p = ifap; p != NULL; p = p->ifa_next) { if (p->ifa_addr == NULL) @@ -1704,7 +1702,7 @@ set_localaddrs(void) #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN sain->sin_len = sizeof(struct sockaddr_in); #endif - map_add(m, ss_to_text(&ss), NULL); + table_add(m, ss_to_text(&ss), NULL); break; case AF_INET6: @@ -1713,7 +1711,7 @@ set_localaddrs(void) #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif - map_add(m, ss_to_text(&ss), NULL); + table_add(m, ss_to_text(&ss), NULL); break; } } diff --git a/smtpd/parser.c b/smtpd/parser.c index 0789c193..adfb6eb1 100644 --- a/smtpd/parser.c +++ b/smtpd/parser.c @@ -45,19 +45,19 @@ static const struct token t_show[]; static const struct token t_show_envelope[]; static const struct token t_show_message[]; static const struct token t_update[]; -static const struct token t_update_map[]; +static const struct token t_update_table[]; static const struct token t_main[] = { - {KEYWORD, "schedule-id", NONE, t_schedule_id}, - {KEYWORD, "schedule-all", SCHEDULE_ALL, NULL}, - {KEYWORD, "show", NONE, t_show}, + {KEYWORD, "schedule-id", NONE, t_schedule_id}, + {KEYWORD, "schedule-all", SCHEDULE_ALL, NULL}, + {KEYWORD, "show", NONE, t_show}, {KEYWORD, "monitor", MONITOR, NULL}, - {KEYWORD, "pause", NONE, t_pause}, - {KEYWORD, "remove", NONE, t_remove}, - {KEYWORD, "resume", NONE, t_resume}, - {KEYWORD, "stop", SHUTDOWN, NULL}, - {KEYWORD, "log", NONE, t_log}, - {KEYWORD, "update", NONE, t_update}, + {KEYWORD, "pause", NONE, t_pause}, + {KEYWORD, "remove", NONE, t_remove}, + {KEYWORD, "resume", NONE, t_resume}, + {KEYWORD, "stop", SHUTDOWN, NULL}, + {KEYWORD, "log", NONE, t_log}, + {KEYWORD, "update", NONE, t_update}, {ENDTOKEN, "", NONE, NULL} }; @@ -93,30 +93,30 @@ static const struct token t_pause[] = { {KEYWORD, "mda", PAUSE_MDA, NULL}, {KEYWORD, "mta", PAUSE_MTA, NULL}, {KEYWORD, "smtp", PAUSE_SMTP, NULL}, - {ENDTOKEN, "", NONE, NULL} + {ENDTOKEN, "", NONE, NULL} }; static const struct token t_resume[] = { {KEYWORD, "mda", RESUME_MDA, NULL}, {KEYWORD, "mta", RESUME_MTA, NULL}, {KEYWORD, "smtp", RESUME_SMTP, NULL}, - {ENDTOKEN, "", NONE, NULL} + {ENDTOKEN, "", NONE, NULL} }; static const struct token t_log[] = { - {KEYWORD, "verbose", LOG_VERBOSE, NULL}, - {KEYWORD, "brief", LOG_BRIEF, NULL}, - {ENDTOKEN, "", NONE, NULL} + {KEYWORD, "verbose", LOG_VERBOSE, NULL}, + {KEYWORD, "brief", LOG_BRIEF, NULL}, + {ENDTOKEN, "", NONE, NULL} }; static const struct token t_update[] = { - {KEYWORD, "map", NONE, t_update_map}, - {ENDTOKEN, "", NONE, NULL} + {KEYWORD, "table", NONE, t_update_table}, + {ENDTOKEN, "", NONE, NULL} }; -static const struct token t_update_map[] = { - {VARIABLE, "name", UPDATE_MAP, NULL}, - {ENDTOKEN, "", NONE, NULL} +static const struct token t_update_table[] = { + {VARIABLE, "name", UPDATE_TABLE, NULL}, + {ENDTOKEN, "", NONE, NULL} }; diff --git a/smtpd/parser.h b/smtpd/parser.h index 1197cfe4..ba4893ed 100644 --- a/smtpd/parser.h +++ b/smtpd/parser.h @@ -36,7 +36,7 @@ enum actions { RESUME_MDA, RESUME_MTA, RESUME_SMTP, - UPDATE_MAP, + UPDATE_TABLE, }; struct parse_result { diff --git a/smtpd/queue.c b/smtpd/queue.c index f021d069..d0acb611 100644 --- a/smtpd/queue.c +++ b/smtpd/queue.c @@ -237,7 +237,7 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) IMSG_SCHEDULER_ENVELOPES, imsg->hdr.peerid, 0, -1, &evp, sizeof evp); return; - } + } } if (iev->proc == PROC_MTA || iev->proc == PROC_MDA) { @@ -480,5 +480,5 @@ queue_timeout(int fd, short event, void *p) tv.tv_sec = 0; tv.tv_usec = 10; - evtimer_add(ev, &tv); + evtimer_add(ev, &tv); } diff --git a/smtpd/queue_backend.c b/smtpd/queue_backend.c index 55ab56fd..d4d46495 100644 --- a/smtpd/queue_backend.c +++ b/smtpd/queue_backend.c @@ -218,7 +218,8 @@ queue_envelope_dump_buffer(struct envelope *ep, char *evpbuf, size_t evpbufsize) return (0); if (env->sc_queue_flags & QUEUE_COMPRESS) { - evplen = compress_buffer(evp, evplen, evpbufcom, sizeof evpbufcom); + evplen = compress_buffer(evp, evplen, evpbufcom, + sizeof evpbufcom); if (evplen == 0) return (0); evp = evpbufcom; @@ -240,7 +241,8 @@ queue_envelope_load_buffer(struct envelope *ep, char *evpbuf, size_t evpbufsize) evplen = evpbufsize; if (env->sc_queue_flags & QUEUE_COMPRESS) { - evplen = uncompress_buffer(evp, evplen, evpbufcom, sizeof evpbufcom); + evplen = uncompress_buffer(evp, evplen, evpbufcom, + sizeof evpbufcom); if (evplen == 0) return (0); evp = evpbufcom; @@ -283,16 +285,18 @@ queue_envelope_load(uint64_t evpid, struct envelope *ep) size_t evplen; ep->id = evpid; - evplen = env->sc_queue->envelope(QOP_LOAD, &ep->id, evpbuf, sizeof evpbuf); + evplen = env->sc_queue->envelope(QOP_LOAD, &ep->id, evpbuf, + sizeof evpbuf); if (evplen == 0) return (0); - + if (queue_envelope_load_buffer(ep, evpbuf, evplen)) { if ((e = envelope_validate(ep)) == NULL) { ep->id = evpid; return (1); } - log_debug("debug: invalid envelope %016" PRIx64 ": %s", ep->id, e); + log_debug("debug: invalid envelope %016" PRIx64 ": %s", + ep->id, e); } return (0); } @@ -327,7 +331,8 @@ queue_envelope_learn(struct envelope *ep) ep->id = evpid; return (1); } - log_debug("debug: invalid envelope %016" PRIx64 ": %s", ep->id, e); + log_debug("debug: invalid envelope %016" PRIx64 ": %s", + ep->id, e); } return (0); } @@ -337,7 +342,7 @@ queue_generate_msgid(void) { uint32_t msgid; - while((msgid = arc4random_uniform(0xffffffff)) == 0) + while ((msgid = arc4random_uniform(0xffffffff)) == 0) ; return msgid; @@ -349,7 +354,7 @@ queue_generate_evpid(uint32_t msgid) uint32_t rnd; uint64_t evpid; - while((rnd = arc4random_uniform(0xffffffff)) == 0) + while ((rnd = arc4random_uniform(0xffffffff)) == 0) ; evpid = msgid; diff --git a/smtpd/queue_fsqueue.c b/smtpd/queue_fsqueue.c index 65da871a..e52b9673 100644 --- a/smtpd/queue_fsqueue.c +++ b/smtpd/queue_fsqueue.c @@ -74,9 +74,9 @@ static void fsqueue_qwalk_close(void *); #define PATH_EVPTMP PATH_INCOMING "/envelope.tmp" struct queue_backend queue_backend_fs = { - fsqueue_init, - fsqueue_message, - fsqueue_envelope, + fsqueue_init, + fsqueue_message, + fsqueue_envelope, }; static struct timespec startup; @@ -179,7 +179,8 @@ fsqueue_envelope_create(uint64_t *evpid, char *buf, size_t len) if (queued) fsqueue_envelope_path(*evpid, path, sizeof(path)); else - queue_envelope_incoming_path(*evpid, path, sizeof(path)); + queue_envelope_incoming_path(*evpid, path, + sizeof(path)); if (stat(path, &sb) == -1 && errno == ENOENT) goto found; @@ -270,7 +271,7 @@ fsqueue_message_create(uint32_t *msgid) again: *msgid = queue_generate_msgid(); - + /* prevent possible collision later when moving to Q_QUEUE */ fsqueue_message_path(*msgid, rootdir, sizeof(rootdir)); if (stat(rootdir, &sb) != -1 || errno != ENOENT) @@ -370,11 +371,13 @@ fsqueue_message_corrupt(uint32_t msgid) int retry = 0; fsqueue_message_path(msgid, rootdir, sizeof(rootdir)); - fsqueue_message_corrupt_path(msgid, corruptdir, sizeof(corruptdir)); + fsqueue_message_corrupt_path(msgid, corruptdir, + sizeof(corruptdir)); again: if (stat(corruptdir, &sb) != -1 || errno != ENOENT) { - fsqueue_message_corrupt_path(msgid, corruptdir, sizeof(corruptdir)); + fsqueue_message_corrupt_path(msgid, corruptdir, + sizeof(corruptdir)); snprintf(buf, sizeof(buf), ".%i", retry++); strlcat(corruptdir, buf, sizeof(corruptdir)); goto again; @@ -418,52 +421,40 @@ fsqueue_init(int server) static int fsqueue_message(enum queue_op qop, uint32_t *msgid) { - switch (qop) { - case QOP_CREATE: + switch (qop) { + case QOP_CREATE: return fsqueue_message_create(msgid); - - case QOP_DELETE: + case QOP_DELETE: return fsqueue_message_delete(*msgid); - - case QOP_COMMIT: + case QOP_COMMIT: return fsqueue_message_commit(*msgid); - - case QOP_FD_R: - return fsqueue_message_fd_r(*msgid); - + case QOP_FD_R: + return fsqueue_message_fd_r(*msgid); case QOP_CORRUPT: return fsqueue_message_corrupt(*msgid); - - default: + default: fatalx("queue_fsqueue_message: unsupported operation."); - } - + } return 0; } static int fsqueue_envelope(enum queue_op qop, uint64_t *evpid, char *buf, size_t len) { - switch (qop) { - case QOP_CREATE: + switch (qop) { + case QOP_CREATE: return fsqueue_envelope_create(evpid, buf, len); - - case QOP_DELETE: + case QOP_DELETE: return fsqueue_envelope_delete(*evpid); - - case QOP_LOAD: + case QOP_LOAD: return fsqueue_envelope_load(*evpid, buf, len); - - case QOP_UPDATE: + case QOP_UPDATE: return fsqueue_envelope_update(*evpid, buf, len); - - case QOP_LEARN: + case QOP_LEARN: return fsqueue_envelope_learn(evpid, buf, len); - - default: + default: fatalx("queue_fsqueue_envelope: unsupported operation."); - } - + } return 0; } @@ -504,12 +495,11 @@ static int fsqueue_qwalk(void *hdl, uint64_t *evpid) { struct qwalk *q = hdl; - FTSENT *e; + FTSENT *e; char *tmp; - while ((e = fts_read(q->fts)) != NULL) { - - switch(e->fts_info) { + while ((e = fts_read(q->fts)) != NULL) { + switch (e->fts_info) { case FTS_D: q->depth += 1; if (q->depth == 2 && e->fts_namelen != 2) { @@ -555,5 +545,5 @@ fsqueue_qwalk(void *hdl, uint64_t *evpid) } } - return (0); + return (0); } diff --git a/smtpd/queue_ram.c b/smtpd/queue_ram.c index bcc2f11e..fc42c1fa 100644 --- a/smtpd/queue_ram.c +++ b/smtpd/queue_ram.c @@ -48,9 +48,9 @@ static int queue_ram_message(enum queue_op, uint32_t *); static int queue_ram_envelope(enum queue_op , uint64_t *, char *, size_t); struct queue_backend queue_backend_ram = { - queue_ram_init, - queue_ram_message, - queue_ram_envelope, + queue_ram_init, + queue_ram_message, + queue_ram_envelope, }; struct qr_envelope { @@ -80,13 +80,13 @@ queue_ram_message(enum queue_op qop, uint32_t *msgid) char path[MAXPATHLEN]; uint64_t evpid; struct qr_envelope *evp; - struct qr_message *msg; + struct qr_message *msg; int fd; struct stat sb; FILE *f; - switch (qop) { - case QOP_CREATE: + switch (qop) { + case QOP_CREATE: msg = xcalloc(1, sizeof *msg, "queue_ram_message"); tree_init(&msg->envelopes); do { @@ -100,7 +100,7 @@ queue_ram_message(enum queue_op qop, uint32_t *msgid) tree_xset(&messages, *msgid, msg); return (1); - case QOP_DELETE: + case QOP_DELETE: msg = tree_pop(&messages, *msgid); if (msg == NULL) return (0); @@ -113,7 +113,7 @@ queue_ram_message(enum queue_op qop, uint32_t *msgid) free(msg->buf); return (1); - case QOP_COMMIT: + case QOP_COMMIT: msg = tree_get(&messages, *msgid); if (msg == NULL) return (0); @@ -138,7 +138,7 @@ queue_ram_message(enum queue_op qop, uint32_t *msgid) stat_increment("queue.ram.message.size", msg->len); return (1); - case QOP_FD_R: + case QOP_FD_R: msg = tree_get(&messages, *msgid); if (msg == NULL) return (0); @@ -147,14 +147,14 @@ queue_ram_message(enum queue_op qop, uint32_t *msgid) return (-1); write(fd, msg->buf, msg->len); lseek(fd, 0, SEEK_SET); - return (fd); + return (fd); case QOP_CORRUPT: return (queue_ram_message(QOP_DELETE, msgid)); - default: + default: fatalx("queue_queue_ram_message: unsupported operation."); - } + } return (0); } @@ -176,8 +176,8 @@ queue_ram_envelope(enum queue_op qop, uint64_t *evpid, char *buf, size_t len) return (0); } - switch (qop) { - case QOP_CREATE: + switch (qop) { + case QOP_CREATE: do { *evpid = queue_generate_evpid(msgid); } while (tree_check(&msg->envelopes, *evpid)); @@ -188,7 +188,7 @@ queue_ram_envelope(enum queue_op qop, uint64_t *evpid, char *buf, size_t len) tree_xset(&msg->envelopes, *evpid, evp); return (1); - case QOP_DELETE: + case QOP_DELETE: evp = tree_pop(&msg->envelopes, *evpid); if (evp == NULL) return (0); @@ -204,7 +204,7 @@ queue_ram_envelope(enum queue_op qop, uint64_t *evpid, char *buf, size_t len) } return (1); - case QOP_LOAD: + case QOP_LOAD: evp = tree_get(&msg->envelopes, *evpid); if (evp == NULL) { log_debug("cannot find envelope %016" PRIx64, *evpid); @@ -217,7 +217,7 @@ queue_ram_envelope(enum queue_op qop, uint64_t *evpid, char *buf, size_t len) memmove(buf, evp->buf, evp->len); return (evp->len); - case QOP_UPDATE: + case QOP_UPDATE: evp = tree_get(&msg->envelopes, *evpid); if (evp == NULL) return (0); @@ -228,9 +228,9 @@ queue_ram_envelope(enum queue_op qop, uint64_t *evpid, char *buf, size_t len) evp->buf = xmemdup(buf, len, "queue_ram_envelope: update"); return (1); - default: + default: fatalx("queue_queue_ram_envelope: unsupported operation."); - } + } return (0); } diff --git a/smtpd/ruleset.c b/smtpd/ruleset.c index 23b224e0..d2f81f08 100644 --- a/smtpd/ruleset.c +++ b/smtpd/ruleset.c @@ -36,7 +36,8 @@ #include "log.h" -static int ruleset_check_source(struct map *, const struct sockaddr_storage *); +static int ruleset_check_source(struct table *, + const struct sockaddr_storage *); static int ruleset_match_mask(struct sockaddr_storage *, struct netaddr *); static int ruleset_inet4_match(struct sockaddr_in *, struct netaddr *); static int ruleset_inet6_match(struct sockaddr_in6 *, struct netaddr *); @@ -48,7 +49,7 @@ ruleset_match(const struct envelope *evp) const struct mailaddr *maddr = &evp->dest; const struct sockaddr_storage *ss = &evp->ss; struct rule *r; - struct map *map; + struct table *table; struct mapel *me; int v; @@ -74,18 +75,20 @@ ruleset_match(const struct envelope *evp) return r; if (r->r_condition.c_type == COND_DOM) { - map = map_find(r->r_condition.c_map); - if (map == NULL) - fatal("failed to lookup map."); - - if (! strcmp(map->m_src, "static")) { - TAILQ_FOREACH(me, &map->m_contents, me_entry) { - if (hostname_match(maddr->domain, me->me_key)) + table = table_find(r->r_condition.c_table); + if (table == NULL) + fatal("failed to lookup table."); + + if (! strcmp(table->t_src, "static")) { + TAILQ_FOREACH(me, &table->t_contents, + me_entry) { + if (hostname_match(maddr->domain, + me->me_key)) return r; } } - else if (map_lookup(map->m_id, maddr->domain, - K_VIRTUAL) != NULL) { + else if (table_lookup(table->t_id, maddr->domain, + K_VIRTUAL, NULL) > 0) { return (r); } else if (errno) { errno = EAGAIN; @@ -94,7 +97,7 @@ ruleset_match(const struct envelope *evp) } if (r->r_condition.c_type == COND_VDOM) { - v = aliases_vdomain_exists(r->r_condition.c_map, + v = aliases_vdomain_exists(r->r_condition.c_table, maddr->domain); if (v == -1) { errno = EAGAIN; @@ -130,7 +133,7 @@ ruleset_cmp_source(const char *s1, const char *s2) } static int -ruleset_check_source(struct map *map, const struct sockaddr_storage *ss) +ruleset_check_source(struct table *table, const struct sockaddr_storage *ss) { struct mapel *me; @@ -141,8 +144,8 @@ ruleset_check_source(struct map *map, const struct sockaddr_storage *ss) return 1; } - if (! strcmp(map->m_src, "static")) { - TAILQ_FOREACH(me, &map->m_contents, me_entry) { + if (! strcmp(table->t_src, "static")) { + TAILQ_FOREACH(me, &table->t_contents, me_entry) { if (ss->ss_family == AF_LOCAL) { if (!strcmp(me->me_key, "local")) return 1; @@ -153,7 +156,7 @@ ruleset_check_source(struct map *map, const struct sockaddr_storage *ss) } } else { - if (map_compare(map->m_id, ss_to_text(ss), K_NETADDR, + if (table_compare(table->t_id, ss_to_text(ss), K_NETADDR, ruleset_cmp_source)) return (1); if (errno) @@ -188,10 +191,10 @@ ruleset_inet4_match(struct sockaddr_in *ss, struct netaddr *ssmask) mask = htonl(mask); /* (addr & mask) == (net & mask) */ - if ((ss->sin_addr.s_addr & mask) == + if ((ss->sin_addr.s_addr & mask) == (((struct sockaddr_in *)ssmask)->sin_addr.s_addr & mask)) return 1; - + return 0; } @@ -202,17 +205,17 @@ ruleset_inet6_match(struct sockaddr_in6 *ss, struct netaddr *ssmask) struct in6_addr *inmask; struct in6_addr mask; int i; - + bzero(&mask, sizeof(mask)); for (i = 0; i < ssmask->bits / 8; i++) mask.s6_addr[i] = 0xff; i = ssmask->bits % 8; if (i) mask.s6_addr[ssmask->bits / 8] = 0xff00 >> i; - + in = &ss->sin6_addr; inmask = &((struct sockaddr_in6 *)&ssmask->ss)->sin6_addr; - + for (i = 0; i < 16; i++) { if ((in->s6_addr[i] & mask.s6_addr[i]) != (inmask->s6_addr[i] & mask.s6_addr[i])) diff --git a/smtpd/scheduler.c b/smtpd/scheduler.c index fb6d50f8..1bf838bd 100644 --- a/smtpd/scheduler.c +++ b/smtpd/scheduler.c @@ -198,9 +198,11 @@ scheduler_imsg(struct imsgev *iev, struct imsg *imsg) case IMSG_SCHEDULER_SCHEDULE: id = *(uint64_t *)(imsg->data); if (id <= 0xffffffffL) - log_debug("debug: scheduler: scheduling msg:%08" PRIx64, id); + log_debug("debug: scheduler: " + "scheduling msg:%08" PRIx64, id); else - log_debug("debug: scheduler: scheduling evp:%016" PRIx64, id); + log_debug("debug: scheduler: " + "scheduling evp:%016" PRIx64, id); backend->schedule(id); scheduler_reset_events(); return; @@ -208,15 +210,18 @@ scheduler_imsg(struct imsgev *iev, struct imsg *imsg) case IMSG_SCHEDULER_REMOVE: id = *(uint64_t *)(imsg->data); if (id <= 0xffffffffL) - log_debug("debug: scheduler: removing msg:%08" PRIx64, id); + log_debug("debug: scheduler: " + "removing msg:%08" PRIx64, id); else - log_debug("debug: scheduler: removing evp:%016" PRIx64, id); + log_debug("debug: scheduler: " + "removing evp:%016" PRIx64, id); backend->remove(id); scheduler_reset_events(); return; } - errx(1, "scheduler_imsg: unexpected %s imsg", imsg_to_str(imsg->hdr.type)); + errx(1, "scheduler_imsg: unexpected %s imsg", + imsg_to_str(imsg->hdr.type)); } static void @@ -373,7 +378,7 @@ scheduler_timeout(int fd, short event, void *p) fatalx("scheduler_timeout: unknown batch type"); } - evtimer_add(&env->sc_ev, &tv); + evtimer_add(&env->sc_ev, &tv); } static void @@ -419,8 +424,8 @@ scheduler_process_bounce(struct scheduler_batch *batch) while ((e = batch->evpids)) { batch->evpids = e->next; - log_debug("debug: scheduler: evp:%016" PRIx64 " scheduled (bounce)", - e->id); + log_debug("debug: scheduler: evp:%016" PRIx64 + " scheduled (bounce)", e->id); imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_SMTP_ENQUEUE, 0, 0, -1, &e->id, sizeof e->id); free(e); @@ -436,8 +441,8 @@ scheduler_process_mda(struct scheduler_batch *batch) while ((e = batch->evpids)) { batch->evpids = e->next; - log_debug("debug: scheduler: evp:%016" PRIx64 " scheduled (mda)", - e->id); + log_debug("debug: scheduler: evp:%016" PRIx64 + " scheduled (mda)", e->id); imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_MDA_SESS_NEW, 0, 0, -1, &e->id, sizeof e->id); free(e); @@ -456,8 +461,8 @@ scheduler_process_mta(struct scheduler_batch *batch) while ((e = batch->evpids)) { batch->evpids = e->next; - log_debug("debug: scheduler: evp:%016" PRIx64 " scheduled (mta)", - e->id); + log_debug("debug: scheduler: evp:%016" PRIx64 + " scheduled (mta)", e->id); imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_BATCH_APPEND, 0, 0, -1, &e->id, sizeof e->id); free(e); diff --git a/smtpd/scheduler_backend.c b/smtpd/scheduler_backend.c index 53abe0fc..0a03a365 100644 --- a/smtpd/scheduler_backend.c +++ b/smtpd/scheduler_backend.c @@ -70,5 +70,5 @@ scheduler_compute_schedule(struct scheduler_info *sched) delay = ((delay * sched->retry) * sched->retry) / 2; - return (sched->creation + delay); + return (sched->creation + delay); } diff --git a/smtpd/scheduler_ramqueue.c b/smtpd/scheduler_ramqueue.c index 95b5779f..cb97a5c9 100644 --- a/smtpd/scheduler_ramqueue.c +++ b/smtpd/scheduler_ramqueue.c @@ -129,7 +129,7 @@ struct scheduler_backend scheduler_backend_ramqueue = { static struct rq_queue ramqueue; static struct tree updates; -static time_t currtime; +static time_t currtime; extern int verbose; @@ -338,7 +338,7 @@ scheduler_ramqueue_batch(int typemask, struct scheduler_batch *ret) ret->evpids = NULL; ret->evpcount = 0; - while((evp = TAILQ_FIRST(q))) { + while ((evp = TAILQ_FIRST(q))) { TAILQ_REMOVE(q, evp, entry); @@ -428,7 +428,7 @@ scheduler_ramqueue_messages(uint32_t from, uint32_t *dst, size_t size) size_t n; void *i; - for(n = 0, i = NULL; n < size; n++) { + for (n = 0, i = NULL; n < size; n++) { if (tree_iterfrom(&ramqueue.messages, &i, from, &id, NULL) == 0) break; dst[n] = id; @@ -447,8 +447,8 @@ scheduler_ramqueue_envelopes(uint64_t from, struct evpstate *dst, size_t size) if ((msg = tree_get(&ramqueue.messages, evpid_to_msgid(from))) == NULL) return (0); - - for(n = 0, i = NULL; n < size; ) { + + for (n = 0, i = NULL; n < size; ) { if (tree_iterfrom(&msg->envelopes, &i, from, NULL, (void**)&evp) == 0) @@ -534,7 +534,7 @@ rq_queue_merge(struct rq_queue *rq, struct rq_queue *update) } /* need to re-link all envelopes before merging them */ i = NULL; - while((tree_iter(&message->envelopes, &i, &id, + while ((tree_iter(&message->envelopes, &i, &id, (void*)&envelope))) envelope->message = tomessage; tree_merge(&tomessage->envelopes, &message->envelopes); @@ -636,7 +636,7 @@ rq_envelope_remove(struct rq_queue *rq, struct rq_envelope *evp) if (rq->q_mtabatch == evp->message) rq->q_mtabatch = evp->message->q_next; else { - for(m = rq->q_mtabatch; m->q_next; m = m->q_next) + for (m = rq->q_mtabatch; m->q_next; m = m->q_next) if (m->q_next == evp->message) { m->q_next = evp->message->q_next; break; @@ -676,7 +676,8 @@ rq_envelope_to_text(struct rq_envelope *e) else if (e->type == D_MTA) strlcat(buf, "mta", sizeof buf); - snprintf(t, sizeof t, ",expire=%s", duration_to_text(e->expire - currtime)); + snprintf(t, sizeof t, ",expire=%s", + duration_to_text(e->expire - currtime)); strlcat(buf, t, sizeof buf); if (e->flags & RQ_ENVELOPE_PENDING) { @@ -715,10 +716,10 @@ rq_queue_dump(struct rq_queue *rq, const char * name) log_debug("debug: /--- ramqueue: %s", name); i = NULL; - while((tree_iter(&rq->messages, &i, &id, (void*)&message))) { + while ((tree_iter(&rq->messages, &i, &id, (void*)&message))) { log_debug("debug: | msg:%08" PRIx32, message->msgid); j = NULL; - while((tree_iter(&message->envelopes, &j, &id, + while ((tree_iter(&message->envelopes, &j, &id, (void*)&envelope))) log_debug("debug: | %s", rq_envelope_to_text(envelope)); diff --git a/smtpd/smtp.c b/smtpd/smtp.c index a51e4b9d..72902b90 100644 --- a/smtpd/smtp.c +++ b/smtpd/smtp.c @@ -134,7 +134,9 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) case IMSG_QUEUE_TEMPFAIL: skey.s_id = ss->id; - /* do not use lookup since this is not a expected imsg -- eric@ */ + /* do not use lookup since this is not a expected imsg + * -- eric@ + */ s = SPLAY_FIND(sessiontree, &env->sc_sessions, &skey); if (s == NULL) fatalx("smtp: session is gone"); @@ -170,7 +172,8 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) if (env->sc_flags & SMTPD_CONFIGURING) return; env->sc_flags |= SMTPD_CONFIGURING; - env->sc_listeners = calloc(1, sizeof *env->sc_listeners); + env->sc_listeners = calloc(1, + sizeof *env->sc_listeners); env->sc_ssl = calloc(1, sizeof *env->sc_ssl); if (env->sc_listeners == NULL || env->sc_ssl == NULL) fatal(NULL); @@ -186,8 +189,8 @@ smtp_imsg(struct imsgev *iev, struct imsg *imsg) *ssl = *(struct ssl *)imsg->data; ssl->ssl_cert = xstrdup((char *)imsg->data + sizeof *ssl, "smtp:ssl_cert"); - ssl->ssl_key = xstrdup((char *)imsg->data + sizeof *ssl + - ssl->ssl_cert_len, "smtp:ssl_key"); + ssl->ssl_key = xstrdup((char *)imsg->data + + sizeof *ssl + ssl->ssl_cert_len, "smtp:ssl_key"); if (ssl->ssl_dhparams_len) { ssl->ssl_dhparams = xstrdup((char *)imsg->data + sizeof *ssl + ssl->ssl_cert_len + @@ -475,21 +478,24 @@ smtp_accept(int fd, short event, void *p) socklen_t len; if ((s = smtp_new(l)) == NULL) { - log_warnx("warn: smtp: client limit hit, disabling incoming connections"); + log_warnx("warn: smtp: " + "client limit hit, disabling incoming connections"); goto pause; } len = sizeof(s->s_ss); - if ((s->s_io.sock = accept(fd, (struct sockaddr *)&s->s_ss, &len)) == -1) { + if ((s->s_io.sock = accept(fd, (struct sockaddr *)&s->s_ss, &len)) + == -1) { if (errno == ENFILE || errno == EMFILE) { - log_warnx("warn: smtp: fd exhaustion, disabling incoming connections"); + log_warnx("warn: smtp: " + "fd exhaustion, disabling incoming connections"); goto pause; } if (errno == EINTR || errno == ECONNABORTED) return; fatal("smtp_accept"); } - + io_set_timeout(&s->s_io, SMTPD_SESSION_TIMEOUT * 1000); io_set_write(&s->s_io); dns_query_ptr(&s->s_ss, s->s_id); @@ -549,7 +555,8 @@ smtp_destroy(struct session *session) return; if (env->sc_flags & SMTPD_SMTP_DISABLED) { - log_warnx("warn: smtp: fd exaustion over, re-enabling incoming connections"); + log_warnx("warn: smtp: " + "fd exaustion over, re-enabling incoming connections"); env->sc_flags &= ~SMTPD_SMTP_DISABLED; smtp_resume(); } diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c index 0702a733..deffe96d 100644 --- a/smtpd/smtp_session.c +++ b/smtpd/smtp_session.c @@ -216,7 +216,8 @@ session_rfc4954_auth_plain(struct session *s, char *arg) case S_AUTH_INIT: /* String is not NUL terminated, leave room. */ - if ((len = __b64_pton(arg, (unsigned char *)buf, sizeof(buf) - 1)) == -1) + if ((len = __b64_pton(arg, (unsigned char *)buf, + sizeof(buf) - 1)) == -1) goto abort; /* buf is a byte string, NUL terminate. */ buf[len] = '\0'; @@ -269,7 +270,8 @@ session_rfc4954_auth_login(struct session *s, char *arg) case S_AUTH_USERNAME: bzero(a->user, sizeof(a->user)); - if (__b64_pton(arg, (unsigned char *)a->user, sizeof(a->user) - 1) == -1) + if (__b64_pton(arg, (unsigned char *)a->user, + sizeof(a->user) - 1) == -1) goto abort; session_enter_state(s, S_AUTH_PASSWORD); @@ -278,7 +280,8 @@ session_rfc4954_auth_login(struct session *s, char *arg) case S_AUTH_PASSWORD: bzero(a->pass, sizeof(a->pass)); - if (__b64_pton(arg, (unsigned char *)a->pass, sizeof(a->pass) - 1) == -1) + if (__b64_pton(arg, (unsigned char *)a->pass, + sizeof(a->pass) - 1) == -1) goto abort; session_enter_state(s, S_AUTH_FINALIZE); @@ -289,7 +292,7 @@ session_rfc4954_auth_login(struct session *s, char *arg) bzero(a->pass, sizeof(a->pass)); return; - + default: fatal("session_rfc4954_auth_login: unknown state"); } @@ -314,8 +317,9 @@ session_rfc1652_mail_handler(struct session *s, char *args) *body++ = '\0'; if (strncasecmp(body, "AUTH=", 5) == 0) { - log_debug("debug: smtp: AUTH in MAIL FROM command, skipping"); - continue; + log_debug("debug: smtp: " + "AUTH in MAIL FROM command, skipping"); + continue; } if (strncasecmp(body, "BODY=", 5) == 0) { @@ -327,12 +331,13 @@ session_rfc1652_mail_handler(struct session *s, char *args) } else if (strncasecmp("body=8bitmime", body, 13) != 0) { - session_respond(s, "503 5.5.4 Unsupported option %s", body); + session_respond(s, + "503 5.5.4 Unsupported option %s", body); return 1; } } } - + return session_rfc5321_mail_handler(s, args); } @@ -522,7 +527,8 @@ session_rfc5321_data_handler(struct session *s, char *args) static int session_rfc5321_vrfy_handler(struct session *s, char *args) { - session_respond(s, "252 5.5.1 Cannot VRFY; try RCPT to attempt delivery"); + session_respond(s, + "252 5.5.1 Cannot VRFY; try RCPT to attempt delivery"); return 1; } @@ -530,7 +536,8 @@ session_rfc5321_vrfy_handler(struct session *s, char *args) static int session_rfc5321_expn_handler(struct session *s, char *args) { - session_respond(s, "502 5.5.2 Sorry, we do not allow this operation"); + session_respond(s, + "502 5.5.2 Sorry, we do not allow this operation"); return 1; } @@ -538,7 +545,8 @@ session_rfc5321_expn_handler(struct session *s, char *args) static int session_rfc5321_turn_handler(struct session *s, char *args) { - session_respond(s, "502 5.5.2 Sorry, we do not allow this operation"); + session_respond(s, + "502 5.5.2 Sorry, we do not allow this operation"); return 1; } @@ -640,9 +648,10 @@ session_io(struct io *io, int evt) char *line; size_t len; - log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), io_strio(io)); + log_trace(TRACE_IO, "smtp: %p: %s %s", s, io_strevent(evt), + io_strio(io)); - switch(evt) { + switch (evt) { case IO_TLSREADY: s->s_flags |= F_SECURE; @@ -688,7 +697,8 @@ session_io(struct io *io, int evt) /* pipelining not supported */ if (iobuf_len(&s->s_iobuf)) { - session_respond(s, "500 5.0.0 Pipelining not supported"); + session_respond(s, + "500 5.0.0 Pipelining not supported"); session_enter_state(s, S_QUIT); io_set_write(io); return; @@ -728,8 +738,8 @@ session_io(struct io *io, int evt) break; case IO_DISCONNECTED: - log_info("smtp-in: Received disconnect from session %016" PRIx64, - s->s_id); + log_info("smtp-in: " + "Received disconnect from session %016" PRIx64, s->s_id); session_destroy(s, "disconnected"); break; @@ -765,10 +775,11 @@ session_pickup(struct session *s, struct submit_status *ss) case S_CONNECTED: session_enter_state(s, S_INIT); - log_info("smtp-in: New session %016" PRIx64 " from host %s [%s]", - s->s_id, - s->s_hostname, - ss_to_text(&s->s_ss)); + log_info("smtp-in: " + "New session %016" PRIx64 " from host %s [%s]", + s->s_id, + s->s_hostname, + ss_to_text(&s->s_ss)); s->s_msg.session_id = s->s_id; s->s_msg.ss = s->s_ss; session_imsg(s, PROC_MFA, IMSG_MFA_CONNECT, 0, 0, -1, @@ -795,7 +806,7 @@ session_pickup(struct session *s, struct submit_status *ss) break; case S_AUTH_FINALIZE: - strnvis(user, s->s_auth.user, sizeof user, VIS_WHITE | VIS_SAFE); + strnvis(user, s->s_auth.user, sizeof user, VIS_WHITE|VIS_SAFE); if (s->s_flags & F_AUTHENTICATED) { session_respond(s, "235 Authentication succeeded"); log_info("smtp-in: Accepted authentication for user %s " @@ -830,7 +841,10 @@ session_pickup(struct session *s, struct submit_status *ss) session_respond(s, "250-8BITMIME"); session_respond(s, "250-ENHANCEDSTATUSCODES"); - /* XXX - we also want to support reading SIZE from MAIL parameters */ + /* XXX */ + /* we also want to support reading SIZE from MAIL + * parameters + */ session_respond(s, "250-SIZE %zu", env->sc_maxsize); if (ADVERTISE_TLS(s)) @@ -870,7 +884,8 @@ session_pickup(struct session *s, struct submit_status *ss) session_enter_state(s, S_MAIL); else session_enter_state(s, S_RCPT); - session_respond(s, "%d 5.0.0 Recipient rejected: %s@%s", ss->code, + session_respond(s, "%d 5.0.0 Recipient rejected: %s@%s", + ss->code, s->s_msg.rcpt.user, s->s_msg.rcpt.domain); break; @@ -917,7 +932,8 @@ session_pickup(struct session *s, struct submit_status *ss) break; case S_DONE: - session_respond(s, "250 2.0.0 %08x Message accepted for delivery", + session_respond(s, + "250 2.0.0 %08x Message accepted for delivery", evpid_to_msgid(s->s_msg.id)); log_info("smtp-in: Accepted message %08x on session %016" PRIx64 ": from=<%s%s%s>, size=%ld, nrcpts=%zu, proto=%s", diff --git a/smtpd/smtpctl.8 b/smtpd/smtpctl.8 index 0941a68e..064ef758 100644 --- a/smtpd/smtpctl.8 +++ b/smtpd/smtpctl.8 @@ -147,8 +147,8 @@ Displays runtime statistics concerning .Xr smtpd 8 . .It Cm stop Stop the server. -.It Cm update map Ar name -For map backends that provide caching, causes +.It Cm update table Ar name +For table backends that provide caching, causes .Xr smtpd 8 to update the cache. .El diff --git a/smtpd/smtpctl.c b/smtpd/smtpctl.c index a2b72d91..97bd7f8c 100644 --- a/smtpd/smtpctl.c +++ b/smtpd/smtpctl.c @@ -92,10 +92,11 @@ usage(void) extern char *__progname; if (sendmail) - fprintf(stderr, "usage: %s [-tv] [-f from] [-F name] to ..\n", + fprintf(stderr, "usage: %s [-tv] [-f from] [-F name] to ...\n", __progname); else - fprintf(stderr, "usage: %s command [argument ...]\n", __progname); + fprintf(stderr, "usage: %s command [argument ...]\n", + __progname); exit(1); } @@ -155,7 +156,7 @@ next_message(struct imsg *imsg) { ssize_t n; - while(1) { + while (1) { if ((n = imsg_get(ibuf, imsg)) == -1) errx(1, "imsg_get error"); if (n) @@ -263,10 +264,10 @@ main(int argc, char *argv[]) case SHOW_STATS: imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, NULL, 0); break; - case UPDATE_MAP: + case UPDATE_TABLE: if (strlcpy(name, res->data, sizeof name) >= sizeof name) - errx(1, "map name too long."); - imsg_compose(ibuf, IMSG_LKA_UPDATE_MAP, 0, 0, -1, + errx(1, "table name too long."); + imsg_compose(ibuf, IMSG_LKA_UPDATE_TABLE, 0, 0, -1, name, strlen(name) + 1); done = 1; break; @@ -294,12 +295,11 @@ main(int argc, char *argv[]) errx(1, "unknown request (%d)", action); } - while (!done) { - + do { flush(); next_message(&imsg); - switch(action) { + switch (action) { case REMOVE: case SCHEDULE: case SHUTDOWN: @@ -319,7 +319,7 @@ main(int argc, char *argv[]) break; case NONE: break; - case UPDATE_MAP: + case UPDATE_TABLE: break; case MONITOR: @@ -328,7 +328,7 @@ main(int argc, char *argv[]) } imsg_free(&imsg); - } + } while (!done); free(ibuf); return (0); @@ -349,14 +349,14 @@ action_show_queue_message(uint32_t msgid) found = 0; imsg_compose(ibuf, IMSG_SCHEDULER_ENVELOPES, 0, 0, -1, - &evpid, sizeof evpid); + &evpid, sizeof evpid); flush(); - while(1) { + while (1) { next_message(&imsg); if (imsg.hdr.type != IMSG_SCHEDULER_ENVELOPES) errx(1, "unexpected message %i", imsg.hdr.type); - + if (imsg.hdr.len == sizeof imsg.hdr) { imsg_free(&imsg); if (!found || evpid_to_msgid(++evpid) != msgid) @@ -382,7 +382,7 @@ action_show_queue(void) msgid = 0; now = time(NULL); - do { + do { imsg_compose(ibuf, IMSG_SCHEDULER_MESSAGES, 0, 0, -1, &msgid, sizeof msgid); flush(); @@ -476,7 +476,7 @@ show_stats_output(void) bzero(&kv, sizeof kv); - while(1) { + while (1) { imsg_compose(ibuf, IMSG_STATS_GET, 0, 0, -1, &kv, sizeof kv); flush(); next_message(&imsg); @@ -491,7 +491,7 @@ show_stats_output(void) if (strcmp(kvp->key, "uptime") == 0) { duration = time(NULL) - kvp->val.u.counter; - printf("uptime=%zd\n", (size_t)duration); + printf("uptime=%zd\n", (size_t)duration); printf("uptime.human=%s\n", duration_to_text(duration)); } @@ -536,7 +536,7 @@ show_queue(flags) if (chroot(PATH_SPOOL) == -1 || chdir(".") == -1) err(1, "%s", PATH_SPOOL); - while((r = queue_envelope_learn(&envelope)) != -1) + while ((r = queue_envelope_learn(&envelope)) != -1) if (r) show_queue_envelope(&envelope, flags); } @@ -573,7 +573,7 @@ show_queue_envelope(struct envelope *e, int online) if (e->flags) errx(1, "%016" PRIx64 ": unexpected flags 0x%04x", e->id, e->flags); - + if (status[0]) status[strlen(status) - 1] = '\0'; diff --git a/smtpd/smtpd.c b/smtpd/smtpd.c index 101cae3a..9c1fdb78 100644 --- a/smtpd/smtpd.c +++ b/smtpd/smtpd.c @@ -205,7 +205,8 @@ parent_imsg(struct imsgev *iev, struct imsg *imsg) c->cause == NULL) break; if (!n) { - log_debug("debug: smptd: kill request: proc not found"); + log_debug("debug: smptd: " + "kill request: proc not found"); return; } len = imsg->hdr.len - sizeof imsg->hdr; @@ -229,18 +230,24 @@ parent_imsg(struct imsgev *iev, struct imsg *imsg) log_verbose(*(int *)imsg->data); /* forward to other processes */ - imsg_compose_event(env->sc_ievs[PROC_LKA], IMSG_CTL_VERBOSE, - 0, 0, -1, imsg->data, sizeof(int)); - imsg_compose_event(env->sc_ievs[PROC_MDA], IMSG_CTL_VERBOSE, - 0, 0, -1, imsg->data, sizeof(int)); - imsg_compose_event(env->sc_ievs[PROC_MFA], IMSG_CTL_VERBOSE, - 0, 0, -1, imsg->data, sizeof(int)); - imsg_compose_event(env->sc_ievs[PROC_MTA], IMSG_CTL_VERBOSE, - 0, 0, -1, imsg->data, sizeof(int)); - imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_CTL_VERBOSE, - 0, 0, -1, imsg->data, sizeof(int)); - imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CTL_VERBOSE, - 0, 0, -1, imsg->data, sizeof(int)); + imsg_compose_event(env->sc_ievs[PROC_LKA], + IMSG_CTL_VERBOSE, 0, 0, -1, imsg->data, + sizeof(int)); + imsg_compose_event(env->sc_ievs[PROC_MDA], + IMSG_CTL_VERBOSE, 0, 0, -1, imsg->data, + sizeof(int)); + imsg_compose_event(env->sc_ievs[PROC_MFA], + IMSG_CTL_VERBOSE, 0, 0, -1, imsg->data, + sizeof(int)); + imsg_compose_event(env->sc_ievs[PROC_MTA], + IMSG_CTL_VERBOSE, 0, 0, -1, imsg->data, + sizeof(int)); + imsg_compose_event(env->sc_ievs[PROC_QUEUE], + IMSG_CTL_VERBOSE, 0, 0, -1, imsg->data, + sizeof(int)); + imsg_compose_event(env->sc_ievs[PROC_SMTP], + IMSG_CTL_VERBOSE, 0, 0, -1, imsg->data, + sizeof(int)); return; case IMSG_CTL_SHUTDOWN: @@ -337,12 +344,13 @@ parent_send_config_listeners(void) fatal("smtpd: socket"); opt = 1; #ifdef SO_REUSEADDR - if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) - fatal("smtpd: setsockopt"); + if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEADDR, &opt, + sizeof(opt)) < 0) #else - if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) - fatal("smtpd: setsockopt"); + if (setsockopt(l->fd, SOL_SOCKET, SO_REUSEPORT, &opt, + sizeof(opt)) < 0) #endif + fatal("smtpd: setsockopt"); if (bind(l->fd, (struct sockaddr *)&l->ss, SS_LEN(&l->ss)) == -1) fatal("smtpd: bind"); imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_CONF_LISTENER, @@ -387,11 +395,11 @@ void parent_send_config_ruleset(int proc) { struct rule *r; - struct map *m; + struct table *t; struct mapel *mapel; struct filter *f; - - log_debug("debug: parent_send_config_ruleset: reloading rules and maps"); + + log_debug("debug: parent_send_config_ruleset: reloading"); imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_START, 0, 0, -1, NULL, 0); @@ -402,23 +410,26 @@ parent_send_config_ruleset(int proc) } } else { - TAILQ_FOREACH(m, env->sc_maps, m_entry) { - imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_MAP, - 0, 0, -1, m, sizeof(*m)); - TAILQ_FOREACH(mapel, &m->m_contents, me_entry) { - imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_MAP_CONTENT, - 0, 0, -1, mapel, sizeof(*mapel)); + TAILQ_FOREACH(t, env->sc_tables, t_entry) { + imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_TABLE, + 0, 0, -1, t, sizeof(*t)); + TAILQ_FOREACH(mapel, &t->t_contents, me_entry) { + imsg_compose_event(env->sc_ievs[proc], + IMSG_CONF_TABLE_CONTENT, 0, 0, -1, mapel, + sizeof(*mapel)); } } - + TAILQ_FOREACH(r, env->sc_rules, r_entry) { imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_RULE, 0, 0, -1, r, sizeof(*r)); - imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_RULE_SOURCE, - 0, 0, -1, &r->r_sources->m_name, sizeof(r->r_sources->m_name)); + imsg_compose_event(env->sc_ievs[proc], + IMSG_CONF_RULE_SOURCE, 0, 0, -1, + &r->r_sources->t_name, + sizeof(r->r_sources->t_name)); } } - + imsg_compose_event(env->sc_ievs[proc], IMSG_CONF_END, 0, 0, -1, NULL, 0); } @@ -493,8 +504,10 @@ parent_sig_handler(int sig, short event, void *p) case CHILD_ENQUEUE_OFFLINE: if (fail) - log_warnx("warn: smtpd: couldn't enqueue offline " - "message %s; smtpctl %s", child->path, cause); + log_warnx("warn: smtpd: " + "couldn't enqueue offline " + "message %s; smtpctl %s", + child->path, cause); else unlink(child->path); free(child->path); @@ -574,7 +587,9 @@ main(int argc, char *argv[]) else if (strstr(optarg, "stat=") == optarg) backend_stat = strchr(optarg, '=') + 1; else - log_warnx("warn: invalid backend specifier %s", optarg); + log_warnx("warn: " + "invalid backend specifier %s", + optarg); break; case 'd': debug = 2; @@ -582,7 +597,8 @@ main(int argc, char *argv[]) break; case 'D': if (cmdline_symset(optarg) < 0) - log_warnx("warn: could not parse macro definition %s", + log_warnx("warn: " + "could not parse macro definition %s", optarg); break; case 'n': @@ -616,7 +632,8 @@ main(int argc, char *argv[]) else if (!strcmp(optarg, "all")) verbose |= ~TRACE_VERBOSE; else - log_warnx("warn: unknown trace flag \"%s\"", optarg); + log_warnx("warn: unknown trace flag \"%s\"", + optarg); break; case 'P': if (!strcmp(optarg, "smtp")) @@ -673,12 +690,14 @@ main(int argc, char *argv[]) errx(1, "error in offline directory setup"); if (ckdir(PATH_SPOOL PATH_PURGE, 0700, env->sc_pw->pw_uid, 0, 1) == 0) errx(1, "error in purge directory setup"); - if (ckdir(PATH_SPOOL PATH_TEMPORARY, 0700, env->sc_pw->pw_uid, 0, 1) == 0) + if (ckdir(PATH_SPOOL PATH_TEMPORARY, 0700, env->sc_pw->pw_uid, 0, 1) + == 0) errx(1, "error in purge directory setup"); mvpurge(PATH_SPOOL PATH_INCOMING, PATH_SPOOL PATH_PURGE); - if (ckdir(PATH_SPOOL PATH_INCOMING, 0700, env->sc_pw->pw_uid, 0, 1) == 0) + if (ckdir(PATH_SPOOL PATH_INCOMING, 0700, env->sc_pw->pw_uid, 0, 1) + == 0) errx(1, "error in incoming directory setup"); env->sc_queue = queue_backend_lookup(backend_queue); @@ -693,7 +712,7 @@ main(int argc, char *argv[]) errx(1, "could not find stat backend \"%s\"", backend_stat); if (env->sc_queue_compress_algo) { - env->sc_compress = + env->sc_compress = compress_backend_lookup(env->sc_queue_compress_algo); if (env->sc_compress == NULL) errx(1, "could not find queue compress backend \"%s\"", @@ -856,7 +875,8 @@ void imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid, pid_t pid, int fd, void *data, uint16_t datalen) { - if (imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen) == -1) + if (imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen) + == -1) err(1, "%s: imsg_compose(%s)", proc_to_str(smtpd_process), imsg_to_str(type)); @@ -884,7 +904,7 @@ purge_task(int fd, short ev, void *arg) log_warn("warn: purge_task: opendir"); if (n > 2) { - switch(purge_pid = fork()) { + switch (purge_pid = fork()) { case -1: log_warn("warn: purge_task: fork"); break; @@ -923,7 +943,8 @@ forkmda(struct imsgev *iev, uint32_t id, pid_t pid; int n, allout, pipefd[2]; - log_debug("debug: forkmda: to \"%s\" as %s", deliver->to, deliver->user); + log_debug("debug: forkmda: to \"%s\" as %s", + deliver->to, deliver->user); bzero(&u, sizeof (u)); ub = user_backend_lookup(USER_PWD); @@ -1042,12 +1063,13 @@ offline_scan(int fd, short ev, void *arg) errx(1, "smtpd: opendir"); } - while((d = readdir(dir)) != NULL) { + while ((d = readdir(dir)) != NULL) { if (d->d_type != DT_REG) continue; if (offline_add(d->d_name)) { - log_warnx("warn: smtpd: could not add offline message %s", d->d_name); + log_warnx("warn: smtpd: " + "could not add offline message %s", d->d_name); continue; } @@ -1117,7 +1139,6 @@ offline_enqueue(char *name) sb.st_uid); _exit(1); } - if (! S_ISREG(sb.st_mode)) { log_warnx("warn: smtpd: file %s (uid %d) not regular", @@ -1199,7 +1220,7 @@ offline_done(void) offline_running--; - while(offline_running < OFFLINE_QUEUEMAX) { + while (offline_running < OFFLINE_QUEUEMAX) { if ((q = TAILQ_FIRST(&offline_q)) == NULL) break; /* all done */ TAILQ_REMOVE(&offline_q, q, entry); @@ -1221,7 +1242,8 @@ parent_forward_open(char *username) if (! ub->getbyname(&u, username)) return -1; - if (! bsnprintf(pathname, sizeof (pathname), "%s/.forward", u.directory)) + if (! bsnprintf(pathname, sizeof (pathname), "%s/.forward", + u.directory)) fatal("smtpd: parent_forward_open: snprintf"); fd = open(pathname, O_RDONLY); @@ -1353,7 +1375,7 @@ imsg_to_str(int type) { static char buf[32]; - switch(type) { + switch (type) { CASE(IMSG_NONE); CASE(IMSG_CTL_OK); CASE(IMSG_CTL_FAIL); @@ -1362,14 +1384,14 @@ imsg_to_str(int type) CASE(IMSG_CONF_START); CASE(IMSG_CONF_SSL); CASE(IMSG_CONF_LISTENER); - CASE(IMSG_CONF_MAP); - CASE(IMSG_CONF_MAP_CONTENT); + CASE(IMSG_CONF_TABLE); + CASE(IMSG_CONF_TABLE_CONTENT); CASE(IMSG_CONF_RULE); CASE(IMSG_CONF_RULE_SOURCE); CASE(IMSG_CONF_FILTER); CASE(IMSG_CONF_END); - CASE(IMSG_LKA_UPDATE_MAP); + CASE(IMSG_LKA_UPDATE_TABLE); CASE(IMSG_LKA_MAIL); CASE(IMSG_LKA_RCPT); CASE(IMSG_LKA_SECRET); @@ -1438,7 +1460,7 @@ imsg_to_str(int type) CASE(IMSG_DIGEST); CASE(IMSG_STATS); - CASE(IMSG_STATS_GET); + CASE(IMSG_STATS_GET); default: snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type); diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h index 352bda13..bf98c6cf 100644 --- a/smtpd/smtpd.h +++ b/smtpd/smtpd.h @@ -46,11 +46,11 @@ #define MAX_NAME_SIZE 64 #define MAX_HOPS_COUNT 100 -#define DEFAULT_MAX_BODY_SIZE (35*1024*1024) +#define DEFAULT_MAX_BODY_SIZE (35*1024*1024) #define MAX_TAG_SIZE 32 -#define MAX_MAPSOURCE_SIZE 32 +#define MAX_TABLE_BACKEND_SIZE 32 /* return and forward path size */ #define MAX_FILTER_NAME 32 @@ -97,12 +97,12 @@ /* max len of any smtp line */ #define SMTP_LINE_MAX MAX_LINE_SIZE -#define F_STARTTLS 0x01 -#define F_SMTPS 0x02 -#define F_AUTH 0x04 -#define F_SSL (F_SMTPS|F_STARTTLS) -#define F_STARTTLS_REQUIRE 0x08 -#define F_AUTH_REQUIRE 0x10 +#define F_STARTTLS 0x01 +#define F_SMTPS 0x02 +#define F_AUTH 0x04 +#define F_SSL (F_SMTPS|F_STARTTLS) +#define F_STARTTLS_REQUIRE 0x08 +#define F_AUTH_REQUIRE 0x10 #define F_BACKUP 0x20 /* XXX - MUST BE SYNC-ED WITH ROUTE_BACKUP */ @@ -135,7 +135,7 @@ struct userinfo { }; struct user_backend { - int (*getbyname)(struct userinfo *, const char *); + int(*getbyname)(struct userinfo *, const char *); }; @@ -149,7 +149,7 @@ struct relayhost { char hostname[MAXHOSTNAMELEN]; uint16_t port; char cert[PATH_MAX]; - char authmap[MAX_PATH_SIZE]; + char authtable[MAX_PATH_SIZE]; }; enum imsg_type { @@ -161,14 +161,14 @@ enum imsg_type { IMSG_CONF_START, IMSG_CONF_SSL, IMSG_CONF_LISTENER, - IMSG_CONF_MAP, - IMSG_CONF_MAP_CONTENT, + IMSG_CONF_TABLE, + IMSG_CONF_TABLE_CONTENT, IMSG_CONF_RULE, IMSG_CONF_RULE_SOURCE, IMSG_CONF_FILTER, IMSG_CONF_END, - IMSG_LKA_UPDATE_MAP, + IMSG_LKA_UPDATE_TABLE, IMSG_LKA_MAIL, IMSG_LKA_RCPT, @@ -179,10 +179,10 @@ enum imsg_type { IMSG_MDA_DONE, IMSG_MFA_CONNECT, - IMSG_MFA_HELO, - IMSG_MFA_MAIL, - IMSG_MFA_RCPT, - IMSG_MFA_DATALINE, + IMSG_MFA_HELO, + IMSG_MFA_MAIL, + IMSG_MFA_RCPT, + IMSG_MFA_DATALINE, IMSG_MFA_QUIT, IMSG_MFA_CLOSE, IMSG_MFA_RSET, @@ -278,19 +278,21 @@ struct peer { }; -enum map_type { - T_DYNAMIC = 0x01, /* map with external source */ - T_LIST = 0x02, /* map holding a list */ - T_HASH = 0x04, /* map holding a hash table */ +enum table_type { + T_NONE = 0, + T_DYNAMIC = 0x01, /* table with external source */ + T_LIST = 0x02, /* table holding a list */ + T_HASH = 0x04, /* table holding a hash table */ }; -enum map_kind { - K_NONE, - K_ALIAS, - K_VIRTUAL, - K_CREDENTIALS, - K_NETADDR -}; +enum table_service { + K_NONE = 0x00, + K_ALIAS = 0x01, + K_VIRTUAL = 0x02, + K_CREDENTIALS = 0x04, + K_NETADDR = 0x08, + K_USERINFO = 0x10, +}; struct mapel { TAILQ_ENTRY(mapel) me_entry; @@ -298,24 +300,27 @@ struct mapel { char me_val[MAX_LINE_SIZE]; }; -struct map { - TAILQ_ENTRY(map) m_entry; - char m_name[MAX_LINE_SIZE]; - objid_t m_id; - enum map_type m_type; - char m_src[MAX_MAPSOURCE_SIZE]; - char m_config[MAXPATHLEN]; - TAILQ_HEAD(mapel_list, mapel) m_contents; - void *m_handle; +struct table { + TAILQ_ENTRY(table) t_entry; + char t_name[MAX_LINE_SIZE]; + objid_t t_id; + enum table_type t_type; + char t_src[MAX_TABLE_BACKEND_SIZE]; + char t_config[MAXPATHLEN]; + TAILQ_HEAD(mapel_list, mapel) t_contents; + void *t_handle; + struct table_backend *t_backend; }; -struct map_backend { - void *(*open)(struct map *); - void (*update)(struct map *); +struct table_backend { + const unsigned int services; + int (*config)(struct table *, const char *); + void *(*open)(struct table *); + int (*update)(struct table *, const char *); void (*close)(void *); - void *(*lookup)(void *, const char *, enum map_kind); - int (*compare)(void *, const char *, enum map_kind, + int (*lookup)(void *, const char *, enum table_service, void **); + int (*compare)(void *, const char *, enum table_service, int (*)(const char *, const char *)); }; @@ -328,7 +333,7 @@ enum cond_type { struct cond { TAILQ_ENTRY(cond) c_entry; - objid_t c_map; + objid_t c_table; enum cond_type c_type; }; @@ -347,20 +352,20 @@ enum decision { }; struct rule { - TAILQ_ENTRY(rule) r_entry; - enum decision r_decision; - char r_tag[MAX_TAG_SIZE]; - int r_accept; - struct map *r_sources; - struct cond r_condition; - enum action_type r_action; + TAILQ_ENTRY(rule) r_entry; + enum decision r_decision; + char r_tag[MAX_TAG_SIZE]; + int r_accept; + struct table *r_sources; + struct cond r_condition; + enum action_type r_action; union rule_dest { - char buffer[EXPAND_BUFFER]; - struct relayhost relayhost; - } r_value; + char buffer[EXPAND_BUFFER]; + struct relayhost relayhost; + } r_value; struct mailaddr *r_as; - objid_t r_amap; + objid_t r_atable; time_t r_qexpire; }; @@ -411,23 +416,23 @@ enum expand_type { }; struct expandnode { - RB_ENTRY(expandnode) entry; - TAILQ_ENTRY(expandnode) tq_entry; - enum expand_type type; - int sameuser; - int alias; - struct rule *rule; - struct expandnode *parent; - unsigned int depth; + RB_ENTRY(expandnode) entry; + TAILQ_ENTRY(expandnode) tq_entry; + enum expand_type type; + int sameuser; + int alias; + struct rule *rule; + struct expandnode *parent; + unsigned int depth; union { /* * user field handles both expansion user and system user * so we MUST make it large enough to fit a mailaddr user */ - char user[MAX_LOCALPART_SIZE]; - char buffer[EXPAND_BUFFER]; - struct mailaddr mailaddr; - } u; + char user[MAX_LOCALPART_SIZE]; + char buffer[EXPAND_BUFFER]; + struct mailaddr mailaddr; + } u; }; struct expand { @@ -496,7 +501,8 @@ enum envelope_field { EVP_MTA_RELAY_PORT, EVP_MTA_RELAY_FLAGS, EVP_MTA_RELAY_CERT, - EVP_MTA_RELAY_AUTHMAP + EVP_MTA_RELAY_AUTHMAP, + EVP_MTA_RELAY_AUTHTABLE }; @@ -602,46 +608,45 @@ struct session { struct smtpd { - char sc_conffile[MAXPATHLEN]; - size_t sc_maxsize; - -#define SMTPD_OPT_VERBOSE 0x00000001 -#define SMTPD_OPT_NOACTION 0x00000002 - uint32_t sc_opts; -#define SMTPD_CONFIGURING 0x00000001 -#define SMTPD_EXITING 0x00000002 -#define SMTPD_MDA_PAUSED 0x00000004 -#define SMTPD_MTA_PAUSED 0x00000008 -#define SMTPD_SMTP_PAUSED 0x00000010 -#define SMTPD_MDA_BUSY 0x00000020 -#define SMTPD_MTA_BUSY 0x00000040 -#define SMTPD_BOUNCE_BUSY 0x00000080 -#define SMTPD_SMTP_DISABLED 0x00000100 - uint32_t sc_flags; - uint32_t sc_queue_flags; -#define QUEUE_COMPRESS 0x00000001 - char *sc_queue_compress_algo; - int sc_qexpire; - struct event sc_ev; - int *sc_pipes[PROC_COUNT] - [PROC_COUNT]; - struct imsgev *sc_ievs[PROC_COUNT]; - int sc_instances[PROC_COUNT]; - int sc_instance; - char *sc_title[PROC_COUNT]; - struct passwd *sc_pw; - char sc_hostname[MAXHOSTNAMELEN]; - struct queue_backend *sc_queue; - struct compress_backend *sc_compress; - struct scheduler_backend *sc_scheduler; - struct stat_backend *sc_stat; + char sc_conffile[MAXPATHLEN]; + size_t sc_maxsize; + +#define SMTPD_OPT_VERBOSE 0x00000001 +#define SMTPD_OPT_NOACTION 0x00000002 + uint32_t sc_opts; +#define SMTPD_CONFIGURING 0x00000001 +#define SMTPD_EXITING 0x00000002 +#define SMTPD_MDA_PAUSED 0x00000004 +#define SMTPD_MTA_PAUSED 0x00000008 +#define SMTPD_SMTP_PAUSED 0x00000010 +#define SMTPD_MDA_BUSY 0x00000020 +#define SMTPD_MTA_BUSY 0x00000040 +#define SMTPD_BOUNCE_BUSY 0x00000080 +#define SMTPD_SMTP_DISABLED 0x00000100 + uint32_t sc_flags; + uint32_t sc_queue_flags; +#define QUEUE_COMPRESS 0x00000001 + char *sc_queue_compress_algo; + int sc_qexpire; + struct event sc_ev; + int *sc_pipes[PROC_COUNT][PROC_COUNT]; + struct imsgev *sc_ievs[PROC_COUNT]; + int sc_instances[PROC_COUNT]; + int sc_instance; + char *sc_title[PROC_COUNT]; + struct passwd *sc_pw; + char sc_hostname[MAXHOSTNAMELEN]; + struct queue_backend *sc_queue; + struct compress_backend *sc_compress; + struct scheduler_backend *sc_scheduler; + struct stat_backend *sc_stat; time_t sc_uptime; TAILQ_HEAD(filterlist, filter) *sc_filters; TAILQ_HEAD(listenerlist, listener) *sc_listeners; - TAILQ_HEAD(maplist, map) *sc_maps, *sc_maps_reload; + TAILQ_HEAD(tablelist, table) *sc_tables, *sc_tables_reload; TAILQ_HEAD(rulelist, rule) *sc_rules, *sc_rules_reload; SPLAY_HEAD(sessiontree, session) sc_sessions; SPLAY_HEAD(ssltree, ssl) *sc_ssl; @@ -706,7 +711,7 @@ struct dns { struct secret { uint64_t id; - char mapname[MAX_PATH_SIZE]; + char tablename[MAX_PATH_SIZE]; char host[MAXHOSTNAMELEN]; char secret[MAX_LINE_SIZE]; }; @@ -781,26 +786,34 @@ struct mta_task { struct mta_session *session; }; -/* maps return structures */ -struct map_credentials { +/* tables return structures */ +struct table_credentials { char username[MAX_LINE_SIZE]; char password[MAX_LINE_SIZE]; }; -struct map_alias { +struct table_alias { size_t nbnodes; struct expand expand; }; -struct map_virtual { +struct table_virtual { size_t nbnodes; struct expand expand; }; -struct map_netaddr { +struct table_netaddr { struct netaddr netaddr; }; +struct table_userinfo { + char username[MAXLOGNAME]; + char directory[MAXPATHLEN]; + char password[MAXPASSWORDLEN]; + uid_t uid; + gid_t gid; +}; + enum queue_op { QOP_CREATE, QOP_DELETE, @@ -813,16 +826,16 @@ enum queue_op { }; struct queue_backend { - int (*init)(int); - int (*message)(enum queue_op, uint32_t *); - int (*envelope)(enum queue_op, uint64_t *, char *, size_t); + int(*init)(int); + int(*message)(enum queue_op, uint32_t *); + int(*envelope)(enum queue_op, uint64_t *, char *, size_t); }; struct compress_backend { - int (*compress_file)(FILE *, FILE *); - int (*uncompress_file)(FILE *, FILE *); - size_t (*compress_buffer)(char *, size_t, char *, size_t); - size_t (*uncompress_buffer)(char *, size_t, char *, size_t); + int(*compress_file)(FILE *, FILE *); + int(*uncompress_file)(FILE *, FILE *); + size_t(*compress_buffer)(char *, size_t, char *, size_t); + size_t(*uncompress_buffer)(char *, size_t, char *, size_t); }; /* auth structures */ @@ -832,14 +845,14 @@ enum auth_type { }; struct auth_backend { - int (*authenticate)(char *, char *); + int(*authenticate)(char *, char *); }; /* delivery_backend */ struct delivery_backend { - int allow_root; - void (*open)(struct deliver *); + int allow_root; + void(*open)(struct deliver *); }; struct evpstate { @@ -970,9 +983,17 @@ void bounce_add(uint64_t); void bounce_run(uint64_t, int); +/* compress_backend.c */ +struct compress_backend *compress_backend_lookup(const char *); +int compress_file(FILE *, FILE *); +int uncompress_file(FILE *, FILE *); +size_t compress_buffer(char *, size_t, char *, size_t); +size_t uncompress_buffer(char *, size_t, char *, size_t); + + /* config.c */ #define PURGE_LISTENERS 0x01 -#define PURGE_MAPS 0x02 +#define PURGE_TABLES 0x02 #define PURGE_RULES 0x04 #define PURGE_SSL 0x08 #define PURGE_EVERYTHING 0xff @@ -1016,6 +1037,7 @@ int envelope_ascii_dump(enum envelope_field, struct envelope *, char *, size_t); int envelope_load_buffer(struct envelope *, char *, size_t); int envelope_dump_buffer(struct envelope *, char *, size_t); + /* expand.c */ int expand_cmp(struct expandnode *, struct expandnode *); void expand_insert(struct expand *, struct expandnode *); @@ -1023,6 +1045,7 @@ struct expandnode *expand_lookup(struct expand *, struct expandnode *); void expand_free(struct expand *); RB_PROTOTYPE(expandtree, expandnode, nodes, expand_cmp); + /* forward.c */ int forwards_get(int, struct expand *); @@ -1030,26 +1053,11 @@ int forwards_get(int, struct expand *); /* lka.c */ pid_t lka(void); + /* lka_session.c */ void lka_session(struct submit_status *); void lka_session_forward_reply(struct forward_req *, int); -/* map.c */ -void *map_open(struct map *); -void map_update(struct map *); -void map_close(struct map *, void *); - -void *map_lookup(objid_t, const char *, enum map_kind); -int map_compare(objid_t, const char *, enum map_kind, - int (*)(const char *, const char *)); -struct map *map_find(objid_t); -struct map *map_findbyname(const char *); -struct map *map_create(const char *, const char *); -void map_destroy(struct map *); -void map_add(struct map *, const char *, const char *); -void map_delete(struct map *, const char *); -void map_delete_all(struct map *); - /* mda.c */ pid_t mda(void); @@ -1074,17 +1082,21 @@ void mta_route_error(struct mta_route *, const char *); void mta_route_collect(struct mta_route *); const char *mta_route_to_text(struct mta_route *); + /* mta_session.c */ void mta_session(struct mta_route *); void mta_session_imsg(struct imsgev *, struct imsg *); + /* parse.y */ int parse_config(struct smtpd *, const char *, int); int cmdline_symset(char *); + /* queue.c */ pid_t queue(void); + /* queue_backend.c */ uint32_t queue_generate_msgid(void); uint64_t queue_generate_evpid(uint32_t msgid); @@ -1104,13 +1116,6 @@ int queue_envelope_load(uint64_t, struct envelope *); int queue_envelope_update(struct envelope *); int queue_envelope_learn(struct envelope *); -/* compress_backend.c */ -struct compress_backend *compress_backend_lookup(const char *); -int compress_file(FILE *, FILE *); -int uncompress_file(FILE *, FILE *); -size_t compress_buffer(char *, size_t, char *, size_t); -size_t uncompress_buffer(char *, size_t, char *, size_t); - /* ruleset.c */ struct rule *ruleset_match(const struct envelope *); @@ -1119,16 +1124,19 @@ struct rule *ruleset_match(const struct envelope *); /* scheduler.c */ pid_t scheduler(void); + /* scheduler_bakend.c */ struct scheduler_backend *scheduler_backend_lookup(const char *); void scheduler_info(struct scheduler_info *, struct envelope *); time_t scheduler_compute_schedule(struct scheduler_info *); + /* smtp.c */ pid_t smtp(void); void smtp_resume(void); void smtp_destroy(struct session *); + /* smtp_session.c */ void session_init(struct listener *, struct session *); int session_cmp(struct session *, struct session *); @@ -1136,8 +1144,7 @@ void session_io(struct io *, int); void session_pickup(struct session *, struct submit_status *); void session_destroy(struct session *, const char *); void session_respond(struct session *, char *, ...) - __attribute__ ((format (printf, 2, 3))); - + __attribute__((format (printf, 2, 3))); SPLAY_PROTOTYPE(sessiontree, session, s_nodes, session_cmp); @@ -1171,13 +1178,29 @@ struct stat_backend *stat_backend_lookup(const char *); void stat_increment(const char *, size_t); void stat_decrement(const char *, size_t); void stat_set(const char *, const struct stat_value *); - struct stat_value *stat_counter(size_t); struct stat_value *stat_timestamp(time_t); struct stat_value *stat_timeval(struct timeval *); struct stat_value *stat_timespec(struct timespec *); +/* table.c */ +void *table_open(struct table *); +void table_update(struct table *); +void table_close(struct table *, void *); +int table_config_parser(struct table *, const char *); +int table_lookup(objid_t, const char *, enum table_service, void **); +int table_compare(objid_t, const char *, enum table_service, + int(*)(const char *, const char *)); +struct table *table_find(objid_t); +struct table *table_findbyname(const char *); +struct table *table_create(const char *, const char *, const char *); +void table_destroy(struct table *); +void table_add(struct table *, const char *, const char *); +void table_delete(struct table *, const char *); +void table_delete_all(struct table *); + + /* tree.c */ SPLAY_HEAD(tree, treeentry); #define tree_init(t) SPLAY_INIT((t)) @@ -1210,7 +1233,7 @@ struct arglist { void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); int bsnprintf(char *, size_t, const char *, ...) - __attribute__ ((format (printf, 3, 4))); + __attribute__((format (printf, 3, 4))); int mkdirs(char *, mode_t); int safe_fclose(FILE *); int hostname_match(const char *, const char *); @@ -1250,6 +1273,7 @@ void session_socket_no_linger(int); int session_socket_error(int); uint64_t strtoevpid(const char *); + /* waitq.c */ int waitq_wait(void *, void (*)(void *, void *, void *), void *); void waitq_run(void *, void *); diff --git a/smtpd/ssl.c b/smtpd/ssl.c index 2a06992e..c3556e45 100644 --- a/smtpd/ssl.c +++ b/smtpd/ssl.c @@ -149,7 +149,8 @@ ssl_load_certfile(const char *name, uint8_t flags) if (strlcpy(key.ssl_name, name, sizeof(key.ssl_name)) >= sizeof(key.ssl_name)) { - log_warnx("warn: ssl_load_certfile: certificate name truncated"); + log_warnx("warn: ssl_load_certfile: " + "certificate name truncated"); return -1; } @@ -403,11 +404,11 @@ ssl_smtp_init(void *ssl_ctx) log_debug("debug: session_start_ssl: switching to SSL"); if ((ssl = SSL_new(ssl_ctx)) == NULL) - goto err; - if (!SSL_set_ssl_method(ssl, SSLv23_server_method())) - goto err; + goto err; + if (!SSL_set_ssl_method(ssl, SSLv23_server_method())) + goto err; - return (void*)(ssl); + return (void*)(ssl); err: if (ssl != NULL) @@ -451,24 +452,24 @@ get_dh1024(void) 0x02 }; - if ((dh = DH_new()) == NULL) + if ((dh = DH_new()) == NULL) return NULL; - dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); - dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); - if (dh->p == NULL || dh->g == NULL) { + dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); + dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); + if (dh->p == NULL || dh->g == NULL) { DH_free(dh); return NULL; } - return dh; + return dh; } DH * get_dh_from_memory(char *params, size_t len) { BIO *mem; - DH *dh; + DH *dh; mem = BIO_new_mem_buf(params, len); if (mem == NULL) @@ -476,7 +477,7 @@ get_dh_from_memory(char *params, size_t len) dh = PEM_read_bio_DHparams(mem, NULL, NULL, NULL); if (dh == NULL) goto err; - if (dh->p == NULL || dh->g == NULL) + if (dh->p == NULL || dh->g == NULL) goto err; return dh; diff --git a/smtpd/ssl_privsep.c b/smtpd/ssl_privsep.c index 3e45e7fd..9f018372 100644 --- a/smtpd/ssl_privsep.c +++ b/smtpd/ssl_privsep.c @@ -85,15 +85,15 @@ int ssl_by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **); X509_LOOKUP_METHOD x509_mem_lookup = { "Load cert from memory", - NULL, /* new */ - NULL, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - ssl_by_mem_ctrl, /* ctrl */ - NULL, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ + NULL, /* new */ + NULL, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + ssl_by_mem_ctrl, /* ctrl */ + NULL, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ }; #define X509_L_ADD_MEM 3 @@ -133,18 +133,18 @@ ssl_ctx_load_verify_memory(SSL_CTX *ctx, char *buf, off_t len) { X509_LOOKUP *lu; struct iovec iov; - + if ((lu = X509_STORE_add_lookup(ctx->cert_store, &x509_mem_lookup)) == NULL) return (0); - + iov.iov_base = buf; iov.iov_len = len; - + if (!ssl_by_mem_ctrl(lu, X509_L_ADD_MEM, (const char *)&iov, X509_FILETYPE_PEM, NULL)) return (0); - + return (1); } @@ -157,35 +157,35 @@ ssl_by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf, X509_INFO *itmp; BIO *in = NULL; int i, count = 0; - + iov = (const struct iovec *)buf; - + if (type != X509_FILETYPE_PEM) goto done; - + if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL) goto done; - + if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL) goto done; - - for(i = 0; i < sk_X509_INFO_num(inf); i++) { + + for (i = 0; i < sk_X509_INFO_num(inf); i++) { itmp = sk_X509_INFO_value(inf, i); - if(itmp->x509) { + if (itmp->x509) { X509_STORE_add_cert(lu->store_ctx, itmp->x509); count++; } - if(itmp->crl) { + if (itmp->crl) { X509_STORE_add_crl(lu->store_ctx, itmp->crl); count++; } } sk_X509_INFO_pop_free(inf, X509_INFO_free); - + done: if (!count) X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB); - + if (in != NULL) BIO_free(in); return (count); diff --git a/smtpd/stat_backend.c b/smtpd/stat_backend.c index b54cd0b5..e40b0edd 100644 --- a/smtpd/stat_backend.c +++ b/smtpd/stat_backend.c @@ -57,7 +57,8 @@ stat_increment(const char *name, size_t count) s = buf + sizeof *value; if ((len = strlcpy(s, name, STAT_KEY_SIZE)) >= STAT_KEY_SIZE) { len = STAT_KEY_SIZE - 1; - log_warn("warn: stat_increment: truncated key '%s', ignored", name); + log_warn("warn: stat_increment: truncated key '%s', ignored", + name); } imsg_compose_event(env->sc_ievs[PROC_CONTROL], @@ -76,7 +77,8 @@ stat_decrement(const char *name, size_t count) s = buf + sizeof *value; if ((len = strlcpy(s, name, STAT_KEY_SIZE)) >= STAT_KEY_SIZE) { len = STAT_KEY_SIZE - 1; - log_warn("warn: stat_increment: truncated key '%s', ignored", name); + log_warn("warn: stat_increment: truncated key '%s', ignored", + name); } imsg_compose_event(env->sc_ievs[PROC_CONTROL], @@ -93,7 +95,8 @@ stat_set(const char *name, const struct stat_value *value) s = buf + sizeof *value; if ((len = strlcpy(s, name, STAT_KEY_SIZE)) >= STAT_KEY_SIZE) { len = STAT_KEY_SIZE - 1; - log_warn("warn: stat_increment: truncated key '%s', ignored", name); + log_warn("warn: stat_increment: truncated key '%s', ignored", + name); } imsg_compose_event(env->sc_ievs[PROC_CONTROL], diff --git a/smtpd/table.c b/smtpd/table.c new file mode 100644 index 00000000..6f769bff --- /dev/null +++ b/smtpd/table.c @@ -0,0 +1,339 @@ +/* $OpenBSD: map.c,v 1.35 2012/11/12 14:58:53 eric Exp $ */ + +/* + * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include "sys-queue.h" +#include "sys-tree.h" +#include <sys/param.h> +#include <sys/socket.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <event.h> +#include <imsg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "smtpd.h" +#include "log.h" + +struct table_backend *table_backend_lookup(const char *); + +extern struct table_backend table_backend_static; +extern struct table_backend table_backend_db; +extern struct table_backend table_backend_getpwnam; + +static objid_t last_table_id = 0; + +struct table_backend * +table_backend_lookup(const char *backend) +{ + if (!strcmp(backend, "static") || !strcmp(backend, "file")) + return &table_backend_static; + if (!strcmp(backend, "db")) + return &table_backend_db; + if (!strcmp(backend, "getpwnam")) + return &table_backend_getpwnam; + return NULL; +} + +struct table * +table_findbyname(const char *name) +{ + struct table *t; + + TAILQ_FOREACH(t, env->sc_tables, t_entry) { + if (strcmp(t->t_name, name) == 0) + break; + } + return (t); +} + +struct table * +table_find(objid_t id) +{ + struct table *t; + + TAILQ_FOREACH(t, env->sc_tables, t_entry) { + if (t->t_id == id) + break; + } + return (t); +} + +int +table_lookup(objid_t id, const char *key, enum table_service kind, void **retp) +{ + void *hdl = NULL; + struct table *table; + struct table_backend *backend = NULL; + int ret; + + table = table_find(id); + if (table == NULL) { + errno = EINVAL; + return -1; + } + + backend = table_backend_lookup(table->t_src); + hdl = backend->open(table); + if (hdl == NULL) { + log_warn("warn: table_lookup: can't open %s", table->t_config); + return -1; + } + + ret = backend->lookup(hdl, key, kind, retp); + + backend->close(hdl); + errno = 0; + return ret; +} + +int +table_compare(objid_t id, const char *key, enum table_service kind, + int(*func)(const char *, const char *)) +{ + void *hdl = NULL; + struct table *table; + struct table_backend *backend = NULL; + int ret; + + table = table_find(id); + if (table == NULL) { + errno = EINVAL; + return 0; + } + + backend = table_backend_lookup(table->t_src); + hdl = backend->open(table); + if (hdl == NULL) { + log_warn("warn: table_compare: can't open %s", table->t_config); + if (errno == 0) + errno = ENOTSUP; + return 0; + } + + ret = backend->compare(hdl, key, kind, func); + + backend->close(hdl); + errno = 0; + return ret; +} + +struct table * +table_create(const char *backend, const char *name, const char *config) +{ + struct table *t; + struct table_backend *tb; + size_t n; + + if (name && table_findbyname(name)) + errx(1, "table_create: table \"%s\" already defined", name); + + if ((tb = table_backend_lookup(backend)) == NULL) + errx(1, "table_create: backend \"%s\" does not exist", backend); + + t = xcalloc(1, sizeof(*t), "table_create"); + t->t_backend = tb; + + if (strlcpy(t->t_src, backend, sizeof t->t_src) >= sizeof t->t_src) + errx(1, "table_create: table backend \"%s\" too large", + t->t_src); + + if (config && *config) { + if (strlcpy(t->t_config, config, sizeof t->t_config) + >= sizeof t->t_config) + errx(1, "table_create: table config \"%s\" too large", + t->t_config); + } + + if (strcmp(t->t_src, "static") != 0) + t->t_type = T_DYNAMIC; + + t->t_id = ++last_table_id; + if (t->t_id == INT_MAX) + errx(1, "table_create: too many tables defined"); + + if (name == NULL) + snprintf(t->t_name, sizeof(t->t_name), "<dynamic:%u>", t->t_id); + else { + n = strlcpy(t->t_name, name, sizeof(t->t_name)); + if (n >= sizeof(t->t_name)) + errx(1, "table_create: table name too long"); + } + + TAILQ_INIT(&t->t_contents); + TAILQ_INSERT_TAIL(env->sc_tables, t, t_entry); + + return (t); +} + +void +table_destroy(struct table *t) +{ + struct mapel *me; + + if (strcmp(t->t_src, "static") != 0) + errx(1, "table_add: cannot delete all from table"); + + while ((me = TAILQ_FIRST(&t->t_contents))) { + TAILQ_REMOVE(&t->t_contents, me, me_entry); + free(me); + } + + TAILQ_REMOVE(env->sc_tables, t, t_entry); + free(t); +} + +void +table_add(struct table *t, const char *key, const char *val) +{ + struct mapel *me; + size_t n; + + if (strcmp(t->t_src, "static") != 0) + errx(1, "table_add: cannot add to table"); + + me = xcalloc(1, sizeof(*me), "table_add"); + n = strlcpy(me->me_key, key, sizeof(me->me_key)); + if (n >= sizeof(me->me_key)) + errx(1, "table_add: key too long"); + + if (val) { + n = strlcpy(me->me_val, val, + sizeof(me->me_val)); + if (n >= sizeof(me->me_val)) + errx(1, "table_add: value too long"); + } + + TAILQ_INSERT_TAIL(&t->t_contents, me, me_entry); +} + +void +table_delete(struct table *t, const char *key) +{ + struct mapel *me; + + if (strcmp(t->t_src, "static") != 0) + errx(1, "map_add: cannot delete from map"); + + TAILQ_FOREACH(me, &t->t_contents, me_entry) { + if (strcmp(me->me_key, key) == 0) + break; + } + if (me == NULL) + return; + TAILQ_REMOVE(&t->t_contents, me, me_entry); + free(me); +} + +void * +table_open(struct table *t) +{ + struct table_backend *backend = NULL; + + backend = table_backend_lookup(t->t_src); + if (backend == NULL) + return NULL; + return backend->open(t); +} + +void +table_close(struct table *t, void *hdl) +{ + struct table_backend *backend = NULL; + + backend = table_backend_lookup(t->t_src); + backend->close(hdl); +} + + +void +table_update(struct table *t) +{ + struct table_backend *backend = NULL; + + backend = table_backend_lookup(t->t_src); + backend->update(t, t->t_config[0] ? t->t_config : NULL); +} + +int +table_config_parser(struct table *t, const char *config) +{ + FILE *fp; + char *buf, *lbuf; + size_t flen; + char *keyp; + char *valp; + size_t ret = 0; + + if (strcmp("static", t->t_src) != 0) { + log_warn("table_config_parser: config table must be static"); + return 0; + } + + fp = fopen(config, "r"); + if (fp == NULL) + return 0; + + lbuf = NULL; + while ((buf = fgetln(fp, &flen))) { + if (buf[flen - 1] == '\n') + buf[flen - 1] = '\0'; + else { + lbuf = xmalloc(flen + 1, "table_stdio_get_entry"); + memcpy(lbuf, buf, flen); + lbuf[flen] = '\0'; + buf = lbuf; + } + + keyp = buf; + while (isspace((int)*keyp)) + ++keyp; + if (*keyp == '\0' || *keyp == '#') + continue; + valp = keyp; + strsep(&valp, " \t:"); + if (valp) { + while (*valp && isspace(*valp)) + ++valp; + if (*valp == '\0') + valp = NULL; + } + + /**/ + if (t->t_type == 0) + t->t_type = (valp == keyp) ? T_LIST : T_HASH; + + if ((valp == keyp || valp == NULL) && t->t_type == T_LIST) + table_add(t, keyp, NULL); + else if ((valp != keyp && valp != NULL) && t->t_type == T_HASH) + table_add(t, keyp, valp); + else + goto end; + } + ret = 1; +end: + free(lbuf); + fclose(fp); + return ret; +} diff --git a/smtpd/table_db.c b/smtpd/table_db.c new file mode 100644 index 00000000..de1bdf20 --- /dev/null +++ b/smtpd/table_db.c @@ -0,0 +1,327 @@ +/* $OpenBSD: map_db.c,v 1.12 2012/11/12 14:58:53 eric Exp $ */ + +/* + * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include "sys-queue.h" +#include "sys-tree.h" +#include <sys/param.h> +#include <sys/socket.h> + +#ifdef HAVE_DB_H +#include <db.h> +#elif defined(HAVE_DB1_DB_H) +#include <db1/db.h> +#elif defined(HAVE_DB_185_H) +#include <db_185.h> +#endif +#include <ctype.h> +#include <err.h> +#include <event.h> +#include <fcntl.h> +#include <imsg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "smtpd.h" +#include "log.h" + + +/* db(3) backend */ +static int table_db_config(struct table *, const char *); +static int table_db_update(struct table *, const char *); +static void *table_db_open(struct table *); +static int table_db_lookup(void *, const char *, enum table_service, void **); +static int table_db_compare(void *, const char *, enum table_service, + int(*)(const char *, const char *)); +static void table_db_close(void *); + +static char *table_db_get_entry(void *, const char *, size_t *); + +static int table_db_credentials(const char *, char *, size_t, void **); +static int table_db_alias(const char *, char *, size_t, void **); +static int table_db_virtual(const char *, char *, size_t, void **); +static int table_db_netaddr(const char *, char *, size_t, void **); + +struct table_backend table_backend_db = { + K_ALIAS|K_VIRTUAL|K_CREDENTIALS|K_NETADDR, + table_db_config, + table_db_open, + table_db_update, + table_db_close, + table_db_lookup, + table_db_compare +}; + +static int +table_db_config(struct table *table, const char *config) +{ + return 1; +} + +static int +table_db_update(struct table *table, const char *config) +{ + return 1; +} + +static void * +table_db_open(struct table *table) +{ + return dbopen(table->t_config, O_RDONLY, 0600, DB_HASH, NULL); +} + +static void +table_db_close(void *hdl) +{ + DB *db = hdl; + + db->close(db); +} + +static int +table_db_lookup(void *hdl, const char *key, enum table_service kind, void **retp) +{ + char *line; + size_t len; + int ret; + + line = table_db_get_entry(hdl, key, &len); + if (line == NULL) + return 0; + + ret = 0; + switch (kind) { + case K_ALIAS: + ret = table_db_alias(key, line, len, retp); + break; + + case K_CREDENTIALS: + ret = table_db_credentials(key, line, len, retp); + break; + + case K_VIRTUAL: + ret = table_db_virtual(key, line, len, retp); + break; + + case K_NETADDR: + ret = table_db_netaddr(key, line, len, retp); + break; + + default: + break; + } + + free(line); + + return ret; +} + +static int +table_db_compare(void *hdl, const char *key, enum table_service kind, + int(*func)(const char *, const char *)) +{ + int ret = 0; + DB *db = hdl; + DBT dbk; + DBT dbd; + int r; + char *buf = NULL; + + for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r; + r = db->seq(db, &dbk, &dbd, R_NEXT)) { + buf = xmemdup(dbk.data, dbk.size + 1, "table_db_compare"); + log_debug("debug: key: %s, buf: %s", key, buf); + if (func(key, buf)) + ret = 1; + free(buf); + if (ret) + break; + } + return ret; +} + +static char * +table_db_get_entry(void *hdl, const char *key, size_t *len) +{ + int ret; + DBT dbk; + DBT dbv; + DB *db = hdl; + char pkey[MAX_LINE_SIZE]; + + /* workaround the stupidity of the DB interface */ + if (strlcpy(pkey, key, sizeof pkey) >= sizeof pkey) + errx(1, "table_db_get_entry: key too long"); + dbk.data = pkey; + dbk.size = strlen(pkey) + 1; + + if ((ret = db->get(db, &dbk, &dbv, 0)) != 0) + return NULL; + + *len = dbv.size; + + return xmemdup(dbv.data, dbv.size, "table_db_get_entry"); +} + +static int +table_db_credentials(const char *key, char *line, size_t len, void **retp) +{ + struct table_credentials *credentials = NULL; + char *p; + + /* credentials are stored as user:password */ + if (len < 3) + return -1; + + /* too big to fit in a smtp session line */ + if (len >= MAX_LINE_SIZE) + return -1; + + p = strchr(line, ':'); + if (p == NULL) + return -1; + + if (p == line || p == line + len - 1) + return -1; + *p++ = '\0'; + + credentials = xcalloc(1, sizeof *credentials, + "table_db_credentials"); + if (strlcpy(credentials->username, line, sizeof(credentials->username)) + >= sizeof(credentials->username)) + goto err; + + if (strlcpy(credentials->password, p, sizeof(credentials->password)) + >= sizeof(credentials->password)) + goto err; + + *retp = credentials; + return 1; + +err: + *retp = NULL; + free(credentials); + return -1; +} + +static int +table_db_alias(const char *key, char *line, size_t len, void **retp) +{ + char *subrcpt; + char *endp; + struct table_alias *table_alias = NULL; + struct expandnode xn; + + table_alias = xcalloc(1, sizeof *table_alias, "table_db_alias"); + + 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'; + + if (! alias_parse(&xn, subrcpt)) + goto error; + + expand_insert(&table_alias->expand, &xn); + table_alias->nbnodes++; + } + *retp = table_alias; + return 1; + +error: + *retp = NULL; + expand_free(&table_alias->expand); + free(table_alias); + return -1; +} + +static int +table_db_virtual(const char *key, char *line, size_t len, void **retp) +{ + char *subrcpt; + char *endp; + struct table_virtual *table_virtual = NULL; + struct expandnode xn; + + /* domain key, discard value */ + if (strchr(key, '@') == NULL) { + *retp = NULL; + return 1; + } + + table_virtual = xcalloc(1, sizeof *table_virtual, + "table_db_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'; + + if (! alias_parse(&xn, subrcpt)) + goto error; + + expand_insert(&table_virtual->expand, &xn); + table_virtual->nbnodes++; + } + + *retp = table_virtual; + return 1; + +error: + *retp = NULL; + expand_free(&table_virtual->expand); + free(table_virtual); + return 0; +} + + +static int +table_db_netaddr(const char *key, char *line, size_t len, void **retp) +{ + struct table_netaddr *table_netaddr = NULL; + + table_netaddr = xcalloc(1, sizeof *table_netaddr, "table_db_netaddr"); + + if (! text_to_netaddr(&table_netaddr->netaddr, line)) + goto error; + + *retp = table_netaddr; + return 1; + +error: + *retp = NULL; + free(table_netaddr); + return 0; +} + diff --git a/smtpd/table_getpwnam.c b/smtpd/table_getpwnam.c new file mode 100644 index 00000000..d7a6bdaa --- /dev/null +++ b/smtpd/table_getpwnam.c @@ -0,0 +1,131 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include "sys-queue.h" +#include "sys-tree.h" +#include <sys/param.h> +#include <sys/socket.h> + +#include <ctype.h> +#include <err.h> +#include <event.h> +#include <fcntl.h> +#include <imsg.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "smtpd.h" +#include "log.h" + + +/* getpwnam(3) backend */ +static int table_getpwnam_config(struct table *, const char *); +static int table_getpwnam_update(struct table *, const char *); +static void *table_getpwnam_open(struct table *); +static int table_getpwnam_lookup(void *, const char *, enum table_service, void **); + +static int table_getpwnam_compare(void *, const char *, enum table_service, + int (*)(const char *, const char *)); +static void table_getpwnam_close(void *); + +struct table_backend table_backend_getpwnam = { + K_USERINFO, + table_getpwnam_config, + table_getpwnam_open, + table_getpwnam_update, + table_getpwnam_close, + table_getpwnam_lookup, + table_getpwnam_compare +}; + + +static int +table_getpwnam_config(struct table *table, const char *config) +{ + if (config) + return 0; + return 1; +} + +static int +table_getpwnam_update(struct table *table, const char *config) +{ + return 1; +} + +static void * +table_getpwnam_open(struct table *table) +{ + return table; +} + +static void +table_getpwnam_close(void *hdl) +{ + return; +} + +static int +table_getpwnam_lookup(void *hdl, const char *key, enum table_service kind, void **ret) +{ + struct table_userinfo *userinfo; + struct passwd *pw; + size_t s; + + if (kind != K_USERINFO) + return -1; + + pw = getpwnam(key); + if (pw == NULL) + return 0; + + if (ret == NULL) + return 1; + + userinfo = xcalloc(1, sizeof *userinfo, "table_getpwnam_lookup"); + userinfo->uid = pw->pw_uid; + userinfo->gid = pw->pw_gid; + s = strlcpy(userinfo->username, pw->pw_name, sizeof(userinfo->username)); + if (s >= sizeof(userinfo->username)) + goto error; + s = strlcpy(userinfo->password, pw->pw_passwd, sizeof(userinfo->password)); + if (s >= sizeof(userinfo->password)) + goto error; + s = strlcpy(userinfo->directory, pw->pw_passwd, sizeof(userinfo->directory)); + if (s >= sizeof(userinfo->directory)) + goto error; + + *ret = userinfo; + return 1; + +error: + free(userinfo); + return -1; +} + +static int +table_getpwnam_compare(void *hdl, const char *key, enum table_service kind, + int (*func)(const char *, const char *)) +{ + return 0; +} diff --git a/smtpd/table_static.c b/smtpd/table_static.c new file mode 100644 index 00000000..3accab4c --- /dev/null +++ b/smtpd/table_static.c @@ -0,0 +1,338 @@ +/* $OpenBSD: map_static.c,v 1.9 2012/11/12 14:58:53 eric Exp $ */ + +/* + * Copyright (c) 2012 Gilles Chehade <gilles@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include "sys-queue.h" +#include "sys-tree.h" +#include <sys/param.h> +#include <sys/socket.h> + +#include <ctype.h> +#include <err.h> +#include <event.h> +#include <fcntl.h> +#include <imsg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "smtpd.h" +#include "log.h" + + +/* static backend */ +static int table_static_config(struct table *, const char *); +static int table_static_update(struct table *, const char *); +static void *table_static_open(struct table *); +static int table_static_lookup(void *, const char *, enum table_service, void **); +static int table_static_compare(void *, const char *, enum table_service, + int(*)(const char *, const char *)); +static void table_static_close(void *); + +static int table_static_credentials(const char *, char *, size_t, void **); +static int table_static_alias(const char *, char *, size_t, void **); +static int table_static_virtual(const char *, char *, size_t, void **); +static int table_static_netaddr(const char *, char *, size_t, void **); + +struct table_backend table_backend_static = { + K_ALIAS|K_VIRTUAL|K_CREDENTIALS|K_NETADDR, + table_static_config, + table_static_open, + table_static_update, + table_static_close, + table_static_lookup, + table_static_compare +}; + +static int +table_static_config(struct table *table, const char *config) +{ + /* no config ? ok */ + if (config == NULL) + return 1; + + return table_config_parser(table, config); +} + +static int +table_static_update(struct table *table, const char *config) +{ + struct table *t; + char name[MAX_LINE_SIZE]; + + /* no config ? ok */ + if (config == NULL) + goto ok; + + t = table_create(table->t_src, NULL, config); + if (! t->t_backend->config(t, config)) + goto err; + + /* update successful, swap table names */ + strlcpy(name, table->t_name, sizeof name); + strlcpy(table->t_name, t->t_name, sizeof table->t_name); + strlcpy(t->t_name, name, sizeof t->t_name); + + /* swap, table id */ + table->t_id = table->t_id ^ t->t_id; + t->t_id = table->t_id ^ t->t_id; + table->t_id = table->t_id ^ t->t_id; + + /* destroy former table */ + table_destroy(table); + +ok: + log_info("info: Table \"%s\" successfully updated", name); + return 1; + +err: + table_destroy(t); + log_info("info: Failed to update table \"%s\"", name); + return 0; +} + +static void * +table_static_open(struct table *table) +{ + return table; +} + +static void +table_static_close(void *hdl) +{ + return; +} + +static int +table_static_lookup(void *hdl, const char *key, enum table_service kind, void **retp) +{ + struct table *m = hdl; + struct mapel *me = NULL; + char *line; + size_t len; + int ret; + + line = NULL; + TAILQ_FOREACH(me, &m->t_contents, me_entry) + if (strcmp(key, me->me_key) == 0) { + line = me->me_val; + break; + } + + if (retp == NULL) + return me ? 1 : 0; + + if (me == NULL) { + *retp = NULL; + return 0; + } + + if ((line = strdup(line)) == NULL) + return -1; + + len = strlen(line); + switch (kind) { + case K_ALIAS: + ret = table_static_alias(key, line, len, retp); + break; + + case K_CREDENTIALS: + ret = table_static_credentials(key, line, len, retp); + break; + + case K_VIRTUAL: + ret = table_static_virtual(key, line, len, retp); + break; + + case K_NETADDR: + ret = table_static_netaddr(key, line, len, retp); + break; + + default: + ret = -1; + } + + free(line); + + return ret; +} + +static int +table_static_compare(void *hdl, const char *key, enum table_service kind, + int(*func)(const char *, const char *)) +{ + struct table *m = hdl; + struct mapel *me = NULL; + int ret = 0; + + TAILQ_FOREACH(me, &m->t_contents, me_entry) { + if (! func(key, me->me_key)) + continue; + ret = 1; + break; + } + + return ret; +} + +static int +table_static_credentials(const char *key, char *line, size_t len, void **retp) +{ + struct table_credentials *credentials = NULL; + char *p; + + /* credentials are stored as user:password */ + if (len < 3) + return -1; + + /* too big to fit in a smtp session line */ + if (len >= MAX_LINE_SIZE) + return -1; + + p = strchr(line, ':'); + if (p == NULL) + return -1; + + if (p == line || p == line + len - 1) + return -1; + *p++ = '\0'; + + credentials = xcalloc(1, sizeof *credentials, + "table_static_credentials"); + if (strlcpy(credentials->username, line, sizeof(credentials->username)) + >= sizeof(credentials->username)) + goto err; + + if (strlcpy(credentials->password, p, sizeof(credentials->password)) + >= sizeof(credentials->password)) + goto err; + + *retp = credentials; + return 1; + +err: + *retp = NULL; + free(credentials); + return -1; +} + +static int +table_static_alias(const char *key, char *line, size_t len, void **retp) +{ + char *subrcpt; + char *endp; + struct table_alias *table_alias = NULL; + struct expandnode xn; + + table_alias = xcalloc(1, sizeof *table_alias, "table_static_alias"); + + 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'; + + if (! alias_parse(&xn, subrcpt)) + goto error; + + expand_insert(&table_alias->expand, &xn); + table_alias->nbnodes++; + } + *retp = table_alias; + return 1; + +error: + *retp = NULL; + expand_free(&table_alias->expand); + free(table_alias); + return -1; +} + +static int +table_static_virtual(const char *key, char *line, size_t len, void **retp) +{ + char *subrcpt; + char *endp; + struct table_virtual *table_virtual = NULL; + struct expandnode xn; + + /* domain key, discard value */ + if (strchr(key, '@') == NULL) { + *retp = NULL; + return 1; + } + + table_virtual = xcalloc(1, sizeof *table_virtual, + "table_static_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'; + + if (! alias_parse(&xn, subrcpt)) + goto error; + + expand_insert(&table_virtual->expand, &xn); + table_virtual->nbnodes++; + } + + *retp = table_virtual; + return 1; + +error: + *retp = NULL; + expand_free(&table_virtual->expand); + free(table_virtual); + return 0; +} + + +static int +table_static_netaddr(const char *key, char *line, size_t len, void **retp) +{ + struct table_netaddr *table_netaddr = NULL; + + table_netaddr = xcalloc(1, sizeof *table_netaddr, + "table_static_netaddr"); + + if (! text_to_netaddr(&table_netaddr->netaddr, line)) + goto error; + + *retp = table_netaddr; + return 1; + +error: + *retp = NULL; + free(table_netaddr); + return 0; +} diff --git a/smtpd/util.c b/smtpd/util.c index d2a92cb1..0f4ee44b 100644 --- a/smtpd/util.c +++ b/smtpd/util.c @@ -362,7 +362,8 @@ mktmpfile(void) char path[MAXPATHLEN]; int fd; - if (! bsnprintf(path, sizeof(path), "%s/smtpd.XXXXXXXXXX", PATH_TEMPORARY)) + if (! bsnprintf(path, sizeof(path), "%s/smtpd.XXXXXXXXXX", + PATH_TEMPORARY)) err(1, "snprintf"); if ((fd = mkstemp(path)) == -1) @@ -426,20 +427,20 @@ valid_localpart(const char *s) */ #define IS_ATEXT(c) (isalnum((int)(c)) || strchr("%+-=_", (c))) nextatom: - if (! IS_ATEXT(*s) || *s == '\0') - return 0; - while (*(++s) != '\0') { - if (*s == '.') - break; - if (IS_ATEXT(*s)) - continue; - return 0; - } - if (*s == '.') { - s++; - goto nextatom; - } - return 1; + if (! IS_ATEXT(*s) || *s == '\0') + return 0; + while (*(++s) != '\0') { + if (*s == '.') + break; + if (IS_ATEXT(*s)) + continue; + return 0; + } + if (*s == '.') { + s++; + goto nextatom; + } + return 1; } int @@ -467,22 +468,22 @@ valid_domainpart(const char *s) } nextsub: - if (!isalnum((int)*s)) - return 0; - while (*(++s) != '\0') { - if (*s == '.') - break; - if (isalnum((int)*s) || *s == '-') - continue; - return 0; - } - if (s[-1] == '-') - return 0; - if (*s == '.') { + if (!isalnum((int)*s)) + return 0; + while (*(++s) != '\0') { + if (*s == '.') + break; + if (isalnum((int)*s) || *s == '-') + continue; + return 0; + } + if (s[-1] == '-') + return 0; + if (*s == '.') { s++; - goto nextsub; + goto nextsub; } - return 1; + return 1; } int @@ -528,25 +529,23 @@ ss_to_text(const struct sockaddr_storage *ss) buf[0] = '\0'; p = buf; - if (ss->ss_family == AF_LOCAL) { + if (ss->ss_family == AF_LOCAL) strlcpy(buf, "local", sizeof buf); - } else if (ss->ss_family == AF_INET) { in_addr_t addr; - + addr = ((const struct sockaddr_in *)ss)->sin_addr.s_addr; - addr = ntohl(addr); - bsnprintf(p, NI_MAXHOST, - "%d.%d.%d.%d", - (addr >> 24) & 0xff, - (addr >> 16) & 0xff, - (addr >> 8) & 0xff, - addr & 0xff); + addr = ntohl(addr); + bsnprintf(p, NI_MAXHOST, "%d.%d.%d.%d", + (addr >> 24) & 0xff, (addr >> 16) & 0xff, + (addr >> 8) & 0xff, + addr & 0xff); } else if (ss->ss_family == AF_INET6) { - const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *)ss; + const struct sockaddr_in6 *in6; const struct in6_addr *in6_addr; + in6 = (const struct sockaddr_in6 *)ss; strlcpy(buf, "IPv6:", sizeof(buf)); p = buf + 5; in6_addr = &in6->sin6_addr; @@ -560,17 +559,18 @@ char * time_to_text(time_t when) { struct tm *lt; - static char buf[40]; + static char buf[40]; char *day[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; char *month[] = {"Jan","Feb","Mar","Apr","May","Jun", - "Jul","Aug","Sep","Oct","Nov","Dec"}; + "Jul","Aug","Sep","Oct","Nov","Dec"}; lt = localtime(&when); - if (lt == NULL || when == 0) + if (lt == NULL || when == 0) fatalx("time_to_text: localtime"); /* We do not use strftime because it is subject to locale substitution*/ - if (! bsnprintf(buf, sizeof(buf), "%s, %d %s %d %02d:%02d:%02d %c%02d%02d (%s)", + if (! bsnprintf(buf, sizeof(buf), + "%s, %d %s %d %02d:%02d:%02d %c%02d%02d (%s)", day[lt->tm_wday], lt->tm_mday, month[lt->tm_mon], lt->tm_year + 1900, lt->tm_hour, lt->tm_min, lt->tm_sec, @@ -579,7 +579,7 @@ time_to_text(time_t when) abs((int)lt->tm_gmtoff % 3600) / 60, lt->tm_zone)) fatalx("time_to_text: bsnprintf"); - + return buf; } @@ -715,7 +715,7 @@ text_to_relayhost(struct relayhost *relay, const char *s) { "smtp://", 0 }, { "smtps://", F_SMTPS }, { "tls://", F_STARTTLS }, - { "smtps+auth://", F_SMTPS|F_AUTH }, + { "smtps+auth://", F_SMTPS|F_AUTH }, { "tls+auth://", F_STARTTLS|F_AUTH }, { "ssl://", F_SMTPS|F_STARTTLS }, { "ssl+auth://", F_SMTPS|F_STARTTLS|F_AUTH } @@ -727,7 +727,8 @@ text_to_relayhost(struct relayhost *relay, const char *s) int len; for (i = 0; i < nitems(schemas); ++i) - if (strncasecmp(schemas[i].name, s, strlen(schemas[i].name)) == 0) + if (strncasecmp(schemas[i].name, s, + strlen(schemas[i].name)) == 0) break; if (i == nitems(schemas)) { @@ -750,7 +751,7 @@ text_to_relayhost(struct relayhost *relay, const char *s) return 0; len = sep - p; } - else + else len = strlen(p); if (strlcpy(relay->hostname, p, sizeof (relay->hostname)) @@ -877,7 +878,8 @@ sa_set_port(struct sockaddr *sa, int port) struct addrinfo hints, *res; int error; - error = getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST); + error = getnameinfo(sa, SA_LEN(sa), hbuf, sizeof(hbuf), NULL, 0, + NI_NUMERICHOST); if (error) fatalx("sa_set_port: getnameinfo failed"); @@ -1112,7 +1114,8 @@ log_envelope(const struct envelope *evp, const char *extra, const char *prefix, if (extra == NULL) extra = ""; - log_info("%s: %s for %016" PRIx64 ": from=<%s@%s>, to=<%s@%s>, %s%sdelay=%s, %sstat=%s", + log_info("%s: %s for %016" PRIx64 ": from=<%s@%s>, to=<%s@%s>, " + "%s%sdelay=%s, %sstat=%s", evp->type == D_MDA ? "delivery" : "relay", prefix, evp->id, evp->sender.user, evp->sender.domain, diff --git a/smtpd/waitq.c b/smtpd/waitq.c index ff34e024..fee793a0 100644 --- a/smtpd/waitq.c +++ b/smtpd/waitq.c @@ -93,7 +93,7 @@ waitq_run(void *tag, void *result) wq = SPLAY_FIND(waitqtree, &waitqs, &key); SPLAY_REMOVE(waitqtree, &waitqs, wq); - while((w = TAILQ_FIRST(&wq->waiters))) { + while ((w = TAILQ_FIRST(&wq->waiters))) { TAILQ_REMOVE(&wq->waiters, w, entry); w->cb(tag, w->arg, result); free(w); |