summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/table_static.c
diff options
context:
space:
mode:
authorEric Faurot <eric@cvs.openbsd.org>2013-05-24 17:03:15 +0000
committerEric Faurot <eric@cvs.openbsd.org>2013-05-24 17:03:15 +0000
commit2e9aedcac52e52c6811fcb9385c3afed4d9521c3 (patch)
tree841da5f86ad60262c3d85a52a96599096a7d9a94 /usr.sbin/smtpd/table_static.c
parent4c1642b4756fcf57a9dd4b45a0aa37feee1230a9 (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.c340
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);
}