diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2013-05-24 17:03:15 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2013-05-24 17:03:15 +0000 |
commit | 2e9aedcac52e52c6811fcb9385c3afed4d9521c3 (patch) | |
tree | 841da5f86ad60262c3d85a52a96599096a7d9a94 /usr.sbin/smtpd/table_static.c | |
parent | 4c1642b4756fcf57a9dd4b45a0aa37feee1230a9 (diff) |
sync with OpenSMTPD 5.3.2
ok gilles@
Diffstat (limited to 'usr.sbin/smtpd/table_static.c')
-rw-r--r-- | usr.sbin/smtpd/table_static.c | 340 |
1 files changed, 89 insertions, 251 deletions
diff --git a/usr.sbin/smtpd/table_static.c b/usr.sbin/smtpd/table_static.c index cd77677ab02..9fe1ceae9f9 100644 --- a/usr.sbin/smtpd/table_static.c +++ b/usr.sbin/smtpd/table_static.c @@ -1,6 +1,7 @@ -/* $OpenBSD: table_static.c,v 1.4 2013/04/12 18:22:49 eric Exp $ */ +/* $OpenBSD: table_static.c,v 1.5 2013/05/24 17:03:14 eric Exp $ */ /* + * Copyright (c) 2013 Eric Faurot <eric@openbsd.org> * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org> * * Permission to use, copy, modify, and distribute this software for any @@ -19,7 +20,6 @@ #include <sys/types.h> #include <sys/queue.h> #include <sys/tree.h> -#include <sys/param.h> #include <sys/socket.h> #include <netinet/in.h> @@ -38,22 +38,14 @@ #include "log.h" /* static backend */ -static int table_static_config(struct table *, const char *); +static int table_static_config(struct table *); static int table_static_update(struct table *); static void *table_static_open(struct table *); static int table_static_lookup(void *, const char *, enum table_service, - void **); -static int table_static_fetch(void *, enum table_service, char **); + union lookup *); +static int table_static_fetch(void *, enum table_service, union lookup *); 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_domain(const char *, char *, size_t, void **); -static int table_static_netaddr(const char *, char *, size_t, void **); -static int table_static_source(const char *, char *, size_t, void **); -static int table_static_userinfo(const char *, char *, size_t, void **); -static int table_static_mailaddr(const char *, char *, size_t, void **); -static int table_static_addrname(const char *, char *, size_t, void **); +static int table_static_parse(struct table *, const char *, enum table_type); struct table_backend table_backend_static = { K_ALIAS|K_CREDENTIALS|K_DOMAIN|K_NETADDR|K_USERINFO|K_SOURCE|K_MAILADDR|K_ADDRNAME, @@ -76,30 +68,99 @@ static struct keycmp { static int -table_static_config(struct table *table, const char *config) +table_static_config(struct table *table) { /* no config ? ok */ - if (config == NULL) + if (*table->t_config == '\0') return 1; - return table_config_parse(table, config, T_LIST|T_HASH); + return table_static_parse(table, table->t_config, T_LIST|T_HASH); +} + +static int +table_static_parse(struct table *t, const char *config, enum table_type type) +{ + FILE *fp; + char *buf, *lbuf; + size_t flen; + char *keyp; + char *valp; + size_t ret = 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_config_parse"); + 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) { + if (!isspace(*valp) && + !(*valp == ':' && isspace(*(valp + 1)))) + break; + ++valp; + } + if (*valp == '\0') + valp = NULL; + } + + /**/ + if (t->t_type == 0) + t->t_type = (valp == keyp || valp == NULL) ? T_LIST : + T_HASH; + + if (!(t->t_type & type)) + goto end; + + 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; } static int table_static_update(struct table *table) { - struct table *t; + struct table *t; + void *p = NULL; /* no config ? ok */ if (table->t_config[0] == '\0') goto ok; - t = table_create(table->t_src, NULL, table->t_config); - if (! t->t_backend->config(t, table->t_config)) + t = table_create("static", table->t_name, "update", table->t_config); + if (!table_config(t)) goto err; /* replace former table, frees t */ - table_replace(table, t); + while (dict_poproot(&table->t_dict, NULL, (void **)&p)) + free(p); + dict_merge(&table->t_dict, &t->t_dict); + table_destroy(t); ok: log_info("info: Table \"%s\" successfully updated", table->t_name); @@ -125,11 +186,10 @@ table_static_close(void *hdl) static int table_static_lookup(void *hdl, const char *key, enum table_service service, - void **retp) + union lookup *lk) { struct table *m = hdl; char *line; - size_t len; int ret; int (*match)(const char *, const char *) = NULL; size_t i; @@ -161,65 +221,20 @@ table_static_lookup(void *hdl, const char *key, enum table_service service, break; } - if (retp == NULL) + if (lk == NULL) return ret ? 1 : 0; - if (ret == 0) { - *retp = NULL; + if (ret == 0) return 0; - } - - if ((line = strdup(line)) == NULL) - return -1; - len = strlen(line); - switch (service) { - 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_DOMAIN: - ret = table_static_domain(key, line, len, retp); - break; - - case K_NETADDR: - ret = table_static_netaddr(key, line, len, retp); - break; - - case K_SOURCE: - ret = table_static_source(key, line, len, retp); - break; - - case K_USERINFO: - ret = table_static_userinfo(key, line, len, retp); - break; - - case K_MAILADDR: - ret = table_static_mailaddr(key, line, len, retp); - break; - - case K_ADDRNAME: - ret = table_static_addrname(key, line, len, retp); - break; - default: - ret = -1; - } - - free(line); - - return ret; + return table_parse_lookup(service, key, line, lk); } static int -table_static_fetch(void *hdl, enum table_service service, char **retp) +table_static_fetch(void *hdl, enum table_service service, union lookup *lk) { struct table *t = hdl; const char *k; - char *line; if (! dict_iter(&t->t_dict, &t->t_iter, &k, (void **)NULL)) { t->t_iter = NULL; @@ -227,185 +242,8 @@ table_static_fetch(void *hdl, enum table_service service, char **retp) return 0; } - if (retp == NULL) + if (lk == NULL) return 1; - if ((line = strdup(k)) == NULL) - return -1; - - *retp = line; - - return 1; -} - -static int -table_static_credentials(const char *key, char *line, size_t len, void **retp) -{ - struct credentials *creds; - char *p; - - /* credentials are stored as user:password */ - if (len < 3) - return -1; - - /* too big to fit in a smtp session line */ - if (len >= SMTPD_MAXLINESIZE) - return -1; - - p = strchr(line, ':'); - if (p == NULL) - return -1; - - if (p == line || p == line + len - 1) - return -1; - *p++ = '\0'; - - creds = xcalloc(1, sizeof *creds, "table_static_credentials"); - if (strlcpy(creds->username, line, sizeof(creds->username)) - >= sizeof(creds->username)) - goto err; - - if (strlcpy(creds->password, p, sizeof(creds->password)) - >= sizeof(creds->password)) - goto err; - - *retp = creds; - return 1; - -err: - *retp = NULL; - free(creds); - return -1; -} - -static int -table_static_alias(const char *key, char *line, size_t len, void **retp) -{ - struct expand *xp; - - xp = xcalloc(1, sizeof *xp, "table_static_alias"); - if (! expand_line(xp, line, 1)) - goto error; - *retp = xp; - return 1; - -error: - *retp = NULL; - expand_free(xp); - return -1; -} - -static int -table_static_netaddr(const char *key, char *line, size_t len, void **retp) -{ - struct netaddr *netaddr; - - netaddr = xcalloc(1, sizeof *netaddr, "table_static_netaddr"); - if (! text_to_netaddr(netaddr, line)) - goto error; - *retp = netaddr; - return 1; - -error: - *retp = NULL; - free(netaddr); - return -1; -} - -static int -table_static_source(const char *key, char *line, size_t len, void **retp) -{ - struct source *source = NULL; - - source = xcalloc(1, sizeof *source, "table_static_source"); - if (inet_pton(AF_INET6, line, &source->addr.in6) != 1) - if (inet_pton(AF_INET, line, &source->addr.in4) != 1) - goto error; - *retp = source; - return 1; - -error: - *retp = NULL; - free(source); - return 0; -} - -static int -table_static_domain(const char *key, char *line, size_t len, void **retp) -{ - struct destination *destination; - - destination = xcalloc(1, sizeof *destination, "table_static_domain"); - if (strlcpy(destination->name, line, sizeof destination->name) - >= sizeof destination->name) - goto error; - *retp = destination; - return 1; - -error: - *retp = NULL; - free(destination); - return -1; -} - -static int -table_static_userinfo(const char *key, char *line, size_t len, void **retp) -{ - struct userinfo *userinfo = NULL; - char buffer[1024]; - - if (! bsnprintf(buffer, sizeof buffer, "%s:%s", key, line)) - goto error; - - userinfo = xcalloc(1, sizeof *userinfo, "table_static_userinfo"); - if (! text_to_userinfo(userinfo, buffer)) - goto error; - *retp = userinfo; - return 1; - -error: - *retp = NULL; - free(userinfo); - return -1; -} - -static int -table_static_mailaddr(const char *key, char *line, size_t len, void **retp) -{ - struct mailaddr *mailaddr; - - mailaddr = xcalloc(1, sizeof *mailaddr, "table_static_mailaddr"); - if (! text_to_mailaddr(mailaddr, line)) - goto error; - *retp = mailaddr; - return 1; - -error: - *retp = NULL; - free(mailaddr); - return -1; -} - -static int -table_static_addrname(const char *key, char *line, size_t len, void **retp) -{ - struct addrname *addrname; - - addrname = xcalloc(1, sizeof *addrname, "table_static_addrname"); - - if (inet_pton(AF_INET6, key, &addrname->addr.in6) != 1) - if (inet_pton(AF_INET, key, &addrname->addr.in4) != 1) - goto error; - - if (strlcpy(addrname->name, line, sizeof addrname->name) - >= sizeof addrname->name) - goto error; - - *retp = addrname; - return 1; - -error: - *retp = NULL; - free(addrname); - return -1; + return table_parse_lookup(service, NULL, k, lk); } |