diff options
Diffstat (limited to 'smtpd/table_static.c')
-rw-r--r-- | smtpd/table_static.c | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/smtpd/table_static.c b/smtpd/table_static.c deleted file mode 100644 index 8f78ae11..00000000 --- a/smtpd/table_static.c +++ /dev/null @@ -1,398 +0,0 @@ -/* $OpenBSD: table_static.c,v 1.32 2018/12/28 14:21:02 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 - * 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/socket.h> - -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <ctype.h> -#include <errno.h> - -#include <event.h> -#include <fcntl.h> -#include <imsg.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> - -#include "smtpd.h" -#include "log.h" - -struct table_static_priv { - int type; - struct dict dict; - void *iter; -}; - -/* static backend */ -static int table_static_config(struct table *); -static int table_static_add(struct table *, const char *, const char *); -static void table_static_dump(struct table *); -static int table_static_update(struct table *); -static int table_static_open(struct table *); -static int table_static_lookup(struct table *, enum table_service, const char *, - char **); -static int table_static_fetch(struct table *, enum table_service, char **); -static void table_static_close(struct table *); - -struct table_backend table_backend_static = { - "static", - K_ALIAS|K_CREDENTIALS|K_DOMAIN|K_NETADDR|K_USERINFO| - K_SOURCE|K_MAILADDR|K_ADDRNAME|K_MAILADDRMAP|K_RELAYHOST| - K_STRING|K_REGEX, - table_static_config, - table_static_add, - table_static_dump, - table_static_open, - table_static_update, - table_static_close, - table_static_lookup, - table_static_fetch -}; - -static struct keycmp { - enum table_service service; - int (*func)(const char *, const char *); -} keycmp[] = { - { K_DOMAIN, table_domain_match }, - { K_NETADDR, table_netaddr_match }, - { K_MAILADDR, table_mailaddr_match }, - { K_REGEX, table_regex_match }, -}; - - -static void -table_static_priv_free(struct table_static_priv *priv) -{ - void *p; - - while (dict_poproot(&priv->dict, (void **)&p)) - if (p != priv) - free(p); - free(priv); -} - -static int -table_static_priv_add(struct table_static_priv *priv, const char *key, const char *val) -{ - char lkey[1024]; - void *old, *new = NULL; - - if (!lowercase(lkey, key, sizeof lkey)) { - errno = ENAMETOOLONG; - return (-1); - } - - if (val) { - new = strdup(val); - if (new == NULL) - return (-1); - } - - /* use priv if value is null, so we can detect duplicate entries */ - old = dict_set(&priv->dict, lkey, new ? new : priv); - if (old) { - if (old != priv) - free(old); - return (1); - } - - return (0); -} - -static int -table_static_priv_load(struct table_static_priv *priv, const char *path) -{ - FILE *fp; - char *buf = NULL, *p; - int lineno = 0; - size_t sz = 0; - ssize_t flen; - char *keyp; - char *valp; - int ret = 0; - - if ((fp = fopen(path, "r")) == NULL) { - log_warn("%s: fopen", path); - return 0; - } - - while ((flen = getline(&buf, &sz, fp)) != -1) { - lineno++; - if (buf[flen - 1] == '\n') - buf[--flen] = '\0'; - - keyp = buf; - while (isspace((unsigned char)*keyp)) { - ++keyp; - --flen; - } - if (*keyp == '\0') - continue; - while (isspace((unsigned char)keyp[flen - 1])) - keyp[--flen] = '\0'; - if (*keyp == '#') { - if (priv->type == T_NONE) { - keyp++; - while (isspace((unsigned char)*keyp)) - ++keyp; - if (!strcmp(keyp, "@list")) - priv->type = T_LIST; - } - continue; - } - - if (priv->type == T_NONE) { - for (p = keyp; *p; p++) { - if (*p == ' ' || *p == '\t' || *p == ':') { - priv->type = T_HASH; - break; - } - } - if (priv->type == T_NONE) - priv->type = T_LIST; - } - - if (priv->type == T_LIST) { - table_static_priv_add(priv, keyp, NULL); - continue; - } - - /* T_HASH */ - valp = keyp; - strsep(&valp, " \t:"); - if (valp) { - while (*valp) { - if (!isspace((unsigned char)*valp) && - !(*valp == ':' && - isspace((unsigned char)*(valp + 1)))) - break; - ++valp; - } - if (*valp == '\0') - valp = NULL; - } - if (valp == NULL) { - log_warnx("%s: invalid map entry line %d", - path, lineno); - goto end; - } - - table_static_priv_add(priv, keyp, valp); - } - - if (ferror(fp)) { - log_warn("%s: getline", path); - goto end; - } - - /* Accept empty alias files; treat them as hashes */ - if (priv->type == T_NONE) - priv->type = T_HASH; - - ret = 1; -end: - free(buf); - fclose(fp); - return ret; -} - -static int -table_static_config(struct table *t) -{ - struct table_static_priv *priv, *old; - - /* already up, and no config file? ok */ - if (t->t_handle && *t->t_config == '\0') - return 1; - - /* new config */ - priv = calloc(1, sizeof(*priv)); - if (priv == NULL) - return 0; - priv->type = t->t_type; - dict_init(&priv->dict); - - if (*t->t_config) { - /* load the config file */ - if (table_static_priv_load(priv, t->t_config) == 0) { - table_static_priv_free(priv); - return 0; - } - } - - if ((old = t->t_handle)) - table_static_priv_free(old); - t->t_handle = priv; - t->t_type = priv->type; - - return 1; -} - -static int -table_static_add(struct table *table, const char *key, const char *val) -{ - struct table_static_priv *priv = table->t_handle; - int r; - - /* cannot add to a table read from a file */ - if (*table->t_config) - return 0; - - if (table->t_type == T_NONE) - table->t_type = val ? T_HASH : T_LIST; - else if (table->t_type == T_LIST && val) - return 0; - else if (table->t_type == T_HASH && val == NULL) - return 0; - - if (priv == NULL) { - if (table_static_config(table) == 0) - return 0; - priv = table->t_handle; - } - - r = table_static_priv_add(priv, key, val); - if (r == -1) - return 0; - return 1; -} - -static void -table_static_dump(struct table *table) -{ - struct table_static_priv *priv = table->t_handle; - const char *key; - char *value; - void *iter; - - iter = NULL; - while (dict_iter(&priv->dict, &iter, &key, (void**)&value)) { - if (value && (void*)value != (void*)priv) - log_debug(" \"%s\" -> \"%s\"", key, value); - else - log_debug(" \"%s\"", key); - } -} - -static int -table_static_update(struct table *table) -{ - if (table_static_config(table) == 1) { - log_info("info: Table \"%s\" successfully updated", table->t_name); - return 1; - } - - log_info("info: Failed to update table \"%s\"", table->t_name); - return 0; -} - -static int -table_static_open(struct table *table) -{ - if (table->t_handle == NULL) - return table_static_config(table); - return 1; -} - -static void -table_static_close(struct table *table) -{ - struct table_static_priv *priv = table->t_handle; - - if (priv) - table_static_priv_free(priv); - table->t_handle = NULL; -} - -static int -table_static_lookup(struct table *table, enum table_service service, const char *key, - char **dst) -{ - struct table_static_priv *priv = table->t_handle; - char *line; - int ret; - int (*match)(const char *, const char *) = NULL; - size_t i; - void *iter; - const char *k; - char *v; - - for (i = 0; i < nitems(keycmp); ++i) - if (keycmp[i].service == service) - match = keycmp[i].func; - - line = NULL; - iter = NULL; - ret = 0; - while (dict_iter(&priv->dict, &iter, &k, (void **)&v)) { - if (match) { - if (match(key, k)) { - line = v; - ret = 1; - } - } - else { - if (strcmp(key, k) == 0) { - line = v; - ret = 1; - } - } - if (ret) - break; - } - - if (dst == NULL) - return ret ? 1 : 0; - - if (ret == 0) - return 0; - - *dst = strdup(line); - if (*dst == NULL) - return -1; - - return 1; -} - -static int -table_static_fetch(struct table *t, enum table_service service, char **dst) -{ - struct table_static_priv *priv = t->t_handle; - const char *k; - - if (!dict_iter(&priv->dict, &priv->iter, &k, (void **)NULL)) { - priv->iter = NULL; - if (!dict_iter(&priv->dict, &priv->iter, &k, (void **)NULL)) - return 0; - } - - *dst = strdup(k); - if (*dst == NULL) - return -1; - - return 1; -} |