aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilles Chehade <gilles@poolp.org>2012-11-15 19:53:54 +0100
committerGilles Chehade <gilles@poolp.org>2012-11-15 19:53:54 +0100
commitb08a98cf23f4acba7e16764420f2804ffb19755c (patch)
tree82aca37919b611057b413aa9662aebfe10578bd5
parenttweak syntax slightly to provide simpler semantic for backend/paths (diff)
downloadOpenSMTPD-b08a98cf23f4acba7e16764420f2804ffb19755c.tar.xz
OpenSMTPD-b08a98cf23f4acba7e16764420f2804ffb19755c.zip
- rework the table API:
* allow lookup() to return an error status * allow lookup() to *not* allocate if we just want to check - adapt the static and db table backends to the new API - adapt every caller to the new API - introduce table_getpwnam, the first K_USERINFO capable backend
-rw-r--r--smtpd/aliases.c46
-rw-r--r--smtpd/lka.c19
-rw-r--r--smtpd/makemap/Makefile2
-rw-r--r--smtpd/ruleset.c2
-rw-r--r--smtpd/smtpd.h4
-rw-r--r--smtpd/smtpd/Makefile1
-rw-r--r--smtpd/table.c17
-rw-r--r--smtpd/table_db.c116
-rw-r--r--smtpd/table_getpwnam.c129
-rw-r--r--smtpd/table_static.c130
10 files changed, 310 insertions, 156 deletions
diff --git a/smtpd/aliases.c b/smtpd/aliases.c
index 1fc2dc8c..94da92f0 100644
--- a/smtpd/aliases.c
+++ b/smtpd/aliases.c
@@ -44,15 +44,16 @@ static int alias_is_include(struct expandnode *, const char *, size_t);
int
aliases_get(objid_t id, struct expand *expand, const char *username)
{
- struct table_alias *table_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));
- table_alias = table_lookup(id, buf, K_ALIAS);
- if (table_alias == NULL)
- return (errno ? -1 : 0);
+ ret = table_lookup(id, buf, K_ALIAS, (void **)&table_alias);
+ if (ret <= 0)
+ return ret;
/* foreach node in table_alias expandtree, we merge */
nbaliases = 0;
@@ -76,26 +77,28 @@ int
aliases_virtual_get(objid_t id, struct expand *expand,
const struct mailaddr *maddr)
{
- struct table_virtual *table_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);
- table_virtual = table_lookup(id, buf, K_VIRTUAL);
- if (table_virtual == NULL) {
- if (errno)
- return (-1);
+ if (ret == 0) {
pbuf = strchr(buf, '@');
- table_virtual = table_lookup(id, pbuf, K_VIRTUAL);
+ ret = table_lookup(id, pbuf, K_VIRTUAL, (void **)&table_virtual);
}
- if (table_virtual == NULL)
- return (errno ? -1 : 0);
+ if (ret <= 0)
+ return ret;
/* foreach node in table_virtual expand, we merge */
nbaliases = 0;
@@ -118,19 +121,16 @@ aliases_virtual_get(objid_t id, struct expand *expand,
int
aliases_vdomain_exists(objid_t id, const char *hostname)
{
- struct table_virtual *table_virtual;
- char buf[MAXHOSTNAMELEN];
+ char buf[MAXHOSTNAMELEN];
+ int ret;
xlowercase(buf, hostname, sizeof(buf));
- table_virtual = table_lookup(id, buf, K_VIRTUAL);
- if (table_virtual == NULL)
- return (errno ? -1 : 0);
+ ret = table_lookup(id, buf, K_VIRTUAL, NULL);
+ if (ret <= 0)
+ return ret;
/* XXX - for now the table API always allocate */
log_debug("debug: aliases_vdomain_exist: '%s' exists", hostname);
- expand_free(&table_virtual->expand);
- free(table_virtual);
-
return 1;
}
diff --git a/smtpd/lka.c b/smtpd/lka.c
index d148b61b..0998f86e 100644
--- a/smtpd/lka.c
+++ b/smtpd/lka.c
@@ -59,6 +59,7 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg)
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) {
@@ -102,7 +103,7 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg)
if (iev->proc == PROC_MTA) {
switch (imsg->hdr.type) {
case IMSG_LKA_SECRET: {
- struct table_credentials *table_credentials;
+ struct table_credentials *table_credentials = NULL;
secret = imsg->data;
table = table_findbyname(secret->tablename);
@@ -113,12 +114,18 @@ lka_imsg(struct imsgev *iev, struct imsg *imsg)
-1, secret, sizeof *secret);
return;
}
- table_credentials = table_lookup(table->t_id, secret->host,
- K_CREDENTIALS);
- log_debug("debug: lka: %s credentials lookup (%d)", secret->host,
- table_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 (table_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,
diff --git a/smtpd/makemap/Makefile b/smtpd/makemap/Makefile
index 004ec739..ff5cca0e 100644
--- a/smtpd/makemap/Makefile
+++ b/smtpd/makemap/Makefile
@@ -18,7 +18,7 @@ CFLAGS+= -Wsign-compare -Wbounded
CFLAGS+= -DNO_IO
SRCS= parse.y makemap.c aliases.c expand.c log.c util.c table.c \
- table_static.c table_db.c tree.c
+ table_static.c table_db.c table_getpwnam.c tree.c
DPADD+= ${LIBUTIL} ${LIBCRYPTO}
LDADD+= -lutil -lcrypto
diff --git a/smtpd/ruleset.c b/smtpd/ruleset.c
index 23f99245..5fcd53ef 100644
--- a/smtpd/ruleset.c
+++ b/smtpd/ruleset.c
@@ -83,7 +83,7 @@ ruleset_match(const struct envelope *evp)
}
}
else if (table_lookup(table->t_id, maddr->domain,
- K_VIRTUAL) != NULL) {
+ K_VIRTUAL, NULL) > 0) {
return (r);
} else if (errno) {
errno = EAGAIN;
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index f01d9e63..682a87cc 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -298,7 +298,7 @@ struct table_backend {
void *(*open)(struct table *);
int (*update)(struct table *, const char *);
void (*close)(void *);
- void *(*lookup)(void *, const char *, enum table_service);
+ int (*lookup)(void *, const char *, enum table_service, void **);
int (*compare)(void *, const char *, enum table_service,
int (*)(const char *, const char *));
};
@@ -1165,7 +1165,7 @@ void *table_open(struct table *);
void table_update(struct table *);
void table_close(struct table *, void *);
int table_config_parser(struct table *, const char *);
-void *table_lookup(objid_t, const char *, enum table_service);
+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);
diff --git a/smtpd/smtpd/Makefile b/smtpd/smtpd/Makefile
index ad53a54d..13fe166c 100644
--- a/smtpd/smtpd/Makefile
+++ b/smtpd/smtpd/Makefile
@@ -22,6 +22,7 @@ SRCS+= delivery_maildir.c
SRCS+= delivery_mbox.c
SRCS+= delivery_mda.c
SRCS+= table_db.c
+SRCS+= table_getpwnam.c
SRCS+= table_static.c
SRCS+= queue_fsqueue.c
SRCS+= queue_ram.c
diff --git a/smtpd/table.c b/smtpd/table.c
index f54e2379..5f01a147 100644
--- a/smtpd/table.c
+++ b/smtpd/table.c
@@ -38,6 +38,7 @@ 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;
@@ -48,6 +49,8 @@ table_backend_lookup(const char *backend)
return &table_backend_static;
if (!strcmp(backend, "db"))
return &table_backend_db;
+ if (!strcmp(backend, "getpwnam"))
+ return &table_backend_getpwnam;
return NULL;
}
@@ -75,30 +78,28 @@ table_find(objid_t id)
return (t);
}
-void *
-table_lookup(objid_t id, const char *key, enum table_service kind)
+int
+table_lookup(objid_t id, const char *key, enum table_service kind, void **retp)
{
void *hdl = NULL;
- char *ret = NULL;
struct table *table;
struct table_backend *backend = NULL;
+ int ret;
table = table_find(id);
if (table == NULL) {
errno = EINVAL;
- return NULL;
+ 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);
- if (errno == 0)
- errno = ENOTSUP;
- return NULL;
+ return -1;
}
- ret = backend->lookup(hdl, key, kind);
+ ret = backend->lookup(hdl, key, kind, retp);
backend->close(hdl);
errno = 0;
diff --git a/smtpd/table_db.c b/smtpd/table_db.c
index 1b4c18fe..44822401 100644
--- a/smtpd/table_db.c
+++ b/smtpd/table_db.c
@@ -40,17 +40,17 @@
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 void *table_db_lookup(void *, const char *, enum table_service);
+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 void *table_db_credentials(const char *, char *, size_t);
-static void *table_db_alias(const char *, char *, size_t);
-static void *table_db_virtual(const char *, char *, size_t);
-static void *table_db_netaddr(const char *, 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,
@@ -62,7 +62,6 @@ struct table_backend table_backend_db = {
table_db_compare
};
-
static int
table_db_config(struct table *table, const char *config)
{
@@ -89,33 +88,33 @@ table_db_close(void *hdl)
db->close(db);
}
-static void *
-table_db_lookup(void *hdl, const char *key, enum table_service kind)
+static int
+table_db_lookup(void *hdl, const char *key, enum table_service kind, void **retp)
{
char *line;
size_t len;
- void *ret;
+ int ret;
line = table_db_get_entry(hdl, key, &len);
if (line == NULL)
- return NULL;
+ return 0;
ret = 0;
switch (kind) {
case K_ALIAS:
- ret = table_db_alias(key, line, len);
+ ret = table_db_alias(key, line, len, retp);
break;
case K_CREDENTIALS:
- ret = table_db_credentials(key, line, len);
+ ret = table_db_credentials(key, line, len, retp);
break;
case K_VIRTUAL:
- ret = table_db_virtual(key, line, len);
+ ret = table_db_virtual(key, line, len, retp);
break;
case K_NETADDR:
- ret = table_db_netaddr(key, line, len);
+ ret = table_db_netaddr(key, line, len, retp);
break;
default:
@@ -174,53 +173,52 @@ table_db_get_entry(void *hdl, const char *key, size_t *len)
return xmemdup(dbv.data, dbv.size, "table_db_get_entry");
}
-static void *
-table_db_credentials(const char *key, char *line, size_t len)
+static int
+table_db_credentials(const char *key, char *line, size_t len, void **retp)
{
- struct table_credentials *table_credentials = NULL;
+ struct table_credentials *credentials = NULL;
char *p;
/* credentials are stored as user:password */
if (len < 3)
- return NULL;
+ return -1;
/* too big to fit in a smtp session line */
if (len >= MAX_LINE_SIZE)
- return NULL;
+ return -1;
p = strchr(line, ':');
if (p == NULL)
- return NULL;
+ return -1;
if (p == line || p == line + len - 1)
- return NULL;
+ return -1;
*p++ = '\0';
- table_credentials = xcalloc(1, sizeof *table_credentials,
+ credentials = xcalloc(1, sizeof *credentials,
"table_db_credentials");
-
- if (strlcpy(table_credentials->username, line,
- sizeof(table_credentials->username)) >=
- sizeof(table_credentials->username))
+ if (strlcpy(credentials->username, line, sizeof(credentials->username))
+ >= sizeof(credentials->username))
goto err;
- if (strlcpy(table_credentials->password, p,
- sizeof(table_credentials->password)) >=
- sizeof(table_credentials->password))
+ if (strlcpy(credentials->password, p, sizeof(credentials->password))
+ >= sizeof(credentials->password))
goto err;
- return table_credentials;
+ *retp = credentials;
+ return 1;
err:
- free(table_credentials);
- return NULL;
+ *retp = NULL;
+ free(credentials);
+ return -1;
}
-static void *
-table_db_alias(const char *key, char *line, size_t len)
+static int
+table_db_alias(const char *key, char *line, size_t len, void **retp)
{
- char *subrcpt;
- char *endp;
+ char *subrcpt;
+ char *endp;
struct table_alias *table_alias = NULL;
struct expandnode xn;
@@ -244,29 +242,32 @@ table_db_alias(const char *key, char *line, size_t len)
expand_insert(&table_alias->expand, &xn);
table_alias->nbnodes++;
}
-
- return table_alias;
+ *retp = table_alias;
+ return 1;
error:
+ *retp = NULL;
expand_free(&table_alias->expand);
free(table_alias);
- return NULL;
+ return -1;
}
-static void *
-table_db_virtual(const char *key, char *line, size_t len)
+static int
+table_db_virtual(const char *key, char *line, size_t len, void **retp)
{
- char *subrcpt;
- char *endp;
+ char *subrcpt;
+ char *endp;
struct table_virtual *table_virtual = NULL;
struct expandnode xn;
- table_virtual = xcalloc(1, sizeof *table_virtual, "table_db_virtual");
-
/* domain key, discard value */
- if (strchr(key, '@') == NULL)
- return table_virtual;
+ 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))
@@ -286,28 +287,33 @@ table_db_virtual(const char *key, char *line, size_t len)
table_virtual->nbnodes++;
}
- return table_virtual;
+ *retp = table_virtual;
+ return 1;
error:
+ *retp = NULL;
expand_free(&table_virtual->expand);
free(table_virtual);
- return NULL;
+ return 0;
}
-static void *
-table_db_netaddr(const char *key, char *line, size_t len)
+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;
+ goto error;
- return table_netaddr;
+ *retp = table_netaddr;
+ return 1;
error:
+ *retp = NULL;
free(table_netaddr);
- return NULL;
+ return 0;
}
+
diff --git a/smtpd/table_getpwnam.c b/smtpd/table_getpwnam.c
new file mode 100644
index 00000000..10277f25
--- /dev/null
+++ b/smtpd/table_getpwnam.c
@@ -0,0 +1,129 @@
+/* $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 <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
index 236864e7..26f80c22 100644
--- a/smtpd/table_static.c
+++ b/smtpd/table_static.c
@@ -39,15 +39,15 @@
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 void *table_static_lookup(void *, const char *, enum table_service);
+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 void *table_static_credentials(const char *, char *, size_t);
-static void *table_static_alias(const char *, char *, size_t);
-static void *table_static_virtual(const char *, char *, size_t);
-static void *table_static_netaddr(const char *, char *, size_t);
+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,
@@ -118,49 +118,53 @@ table_static_close(void *hdl)
return;
}
-static void *
-table_static_lookup(void *hdl, const char *key, enum table_service kind)
+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;
- void *ret;
size_t len;
+ int ret;
line = NULL;
- TAILQ_FOREACH(me, &m->t_contents, me_entry) {
- if (strcmp(key, me->me_key) == 0) {
- if (me->me_val == NULL)
- return NULL;
- line = strdup(me->me_val);
- break;
- }
+ 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 == NULL)
- return NULL;
+ if ((line = strdup(line)) == NULL)
+ return -1;
len = strlen(line);
switch (kind) {
case K_ALIAS:
- ret = table_static_alias(key, line, len);
+ ret = table_static_alias(key, line, len, retp);
break;
case K_CREDENTIALS:
- ret = table_static_credentials(key, line, len);
+ ret = table_static_credentials(key, line, len, retp);
break;
case K_VIRTUAL:
- ret = table_static_virtual(key, line, len);
+ ret = table_static_virtual(key, line, len, retp);
break;
case K_NETADDR:
- ret = table_static_netaddr(key, line, len);
+ ret = table_static_netaddr(key, line, len, retp);
break;
default:
- ret = NULL;
- break;
+ ret = -1;
}
free(line);
@@ -186,50 +190,49 @@ table_static_compare(void *hdl, const char *key, enum table_service kind,
return ret;
}
-static void *
-table_static_credentials(const char *key, char *line, size_t len)
+static int
+table_static_credentials(const char *key, char *line, size_t len, void **retp)
{
- struct table_credentials *table_credentials = NULL;
+ struct table_credentials *credentials = NULL;
char *p;
/* credentials are stored as user:password */
if (len < 3)
- return NULL;
+ return -1;
/* too big to fit in a smtp session line */
if (len >= MAX_LINE_SIZE)
- return NULL;
+ return -1;
p = strchr(line, ':');
if (p == NULL)
- return NULL;
+ return -1;
if (p == line || p == line + len - 1)
- return NULL;
+ return -1;
*p++ = '\0';
- table_credentials = xcalloc(1, sizeof *table_credentials,
+ credentials = xcalloc(1, sizeof *credentials,
"table_static_credentials");
-
- if (strlcpy(table_credentials->username, line,
- sizeof(table_credentials->username)) >=
- sizeof(table_credentials->username))
+ if (strlcpy(credentials->username, line, sizeof(credentials->username))
+ >= sizeof(credentials->username))
goto err;
- if (strlcpy(table_credentials->password, p,
- sizeof(table_credentials->password)) >=
- sizeof(table_credentials->password))
+ if (strlcpy(credentials->password, p, sizeof(credentials->password))
+ >= sizeof(credentials->password))
goto err;
- return table_credentials;
+ *retp = credentials;
+ return 1;
err:
- free(table_credentials);
- return NULL;
+ *retp = NULL;
+ free(credentials);
+ return -1;
}
-static void *
-table_static_alias(const char *key, char *line, size_t len)
+static int
+table_static_alias(const char *key, char *line, size_t len, void **retp)
{
char *subrcpt;
char *endp;
@@ -256,29 +259,32 @@ table_static_alias(const char *key, char *line, size_t len)
expand_insert(&table_alias->expand, &xn);
table_alias->nbnodes++;
}
-
- return table_alias;
+ *retp = table_alias;
+ return 1;
error:
+ *retp = NULL;
expand_free(&table_alias->expand);
free(table_alias);
- return NULL;
+ return -1;
}
-static void *
-table_static_virtual(const char *key, char *line, size_t len)
+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;
- table_virtual = xcalloc(1, sizeof *table_virtual, "table_static_virtual");
-
/* domain key, discard value */
- if (strchr(key, '@') == NULL)
- return table_virtual;
+ 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))
@@ -298,28 +304,32 @@ table_static_virtual(const char *key, char *line, size_t len)
table_virtual->nbnodes++;
}
- return table_virtual;
+ *retp = table_virtual;
+ return 1;
error:
+ *retp = NULL;
expand_free(&table_virtual->expand);
free(table_virtual);
- return NULL;
+ return 0;
}
-static void *
-table_static_netaddr(const char *key, char *line, size_t len)
+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;
+ goto error;
- return table_netaddr;
+ *retp = table_netaddr;
+ return 1;
error:
+ *retp = NULL;
free(table_netaddr);
- return NULL;
+ return 0;
}