summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjung <jung@openbsd.org>2015-11-30 19:54:25 +0000
committerjung <jung@openbsd.org>2015-11-30 19:54:25 +0000
commitf3100b90685ee81355453a29e3cfd732f4ad706b (patch)
treead87c4a56c59482b7b441ebb1e6a00a1ef8f1220
parentRevert the sync -> fsync conversion (at least for the time being) - there (diff)
downloadwireguard-openbsd-f3100b90685ee81355453a29e3cfd732f4ad706b.tar.xz
wireguard-openbsd-f3100b90685ee81355453a29e3cfd732f4ad706b.zip
remove table-passwd, table-sqlite, and table-ldap
about 4k lines seldom used code people who rely on this install mail/opensmtpd-extras direction discussed (and agreed) with many ok gilles
-rw-r--r--usr.sbin/smtpd/Makefile6
-rw-r--r--usr.sbin/smtpd/aldap.c1276
-rw-r--r--usr.sbin/smtpd/aldap.h218
-rw-r--r--usr.sbin/smtpd/ber.c1269
-rw-r--r--usr.sbin/smtpd/ber.h128
-rw-r--r--usr.sbin/smtpd/table-ldap/Makefile30
-rw-r--r--usr.sbin/smtpd/table-passwd/Makefile28
-rw-r--r--usr.sbin/smtpd/table-sqlite/Makefile28
-rw-r--r--usr.sbin/smtpd/table_ldap.c569
-rw-r--r--usr.sbin/smtpd/table_passwd.564
-rw-r--r--usr.sbin/smtpd/table_passwd.c267
-rw-r--r--usr.sbin/smtpd/table_sqlite.c523
12 files changed, 1 insertions, 4405 deletions
diff --git a/usr.sbin/smtpd/Makefile b/usr.sbin/smtpd/Makefile
index 660ecddd536..eb429a6bb1f 100644
--- a/usr.sbin/smtpd/Makefile
+++ b/usr.sbin/smtpd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.13 2015/11/23 13:16:48 gilles Exp $
+# $OpenBSD: Makefile,v 1.14 2015/11/30 19:54:25 jung Exp $
.include <bsd.own.mk>
@@ -6,8 +6,4 @@ SUBDIR = smtpd
SUBDIR+= smtpctl
SUBDIR+= makemap
-SUBDIR+= table-ldap
-SUBDIR+= table-passwd
-SUBDIR+= table-sqlite
-
.include <bsd.subdir.mk>
diff --git a/usr.sbin/smtpd/aldap.c b/usr.sbin/smtpd/aldap.c
deleted file mode 100644
index 796b36107e2..00000000000
--- a/usr.sbin/smtpd/aldap.c
+++ /dev/null
@@ -1,1276 +0,0 @@
-/* $OpenBSD: aldap.c,v 1.8 2015/11/05 12:35:58 jung Exp $ */
-
-/*
- * Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
- * Copyright (c) 2006, 2007 Marc Balmer <mbalmer@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 <errno.h>
-#include <inttypes.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "aldap.h"
-
-#if 0
-#define DEBUG
-#endif
-#define ALDAP_VERSION 3
-
-static struct ber_element *ldap_parse_search_filter(struct ber_element *,
- char *);
-static struct ber_element *ldap_do_parse_search_filter(
- struct ber_element *, char **);
-char **aldap_get_stringset(struct ber_element *);
-char *utoa(char *);
-char *parseval(char *, size_t);
-int aldap_create_page_control(struct ber_element *,
- int, struct aldap_page_control *);
-
-#ifdef DEBUG
-void ldap_debug_elements(struct ber_element *);
-#endif
-
-#ifdef DEBUG
-#define DPRINTF(x...) printf(x)
-#define LDAP_DEBUG(x, y) do { fprintf(stderr, "*** " x "\n"); ldap_debug_elements(y); } while (0)
-#else
-#define DPRINTF(x...) do { } while (0)
-#define LDAP_DEBUG(x, y) do { } while (0)
-#endif
-
-int
-aldap_close(struct aldap *al)
-{
- if (close(al->ber.fd) == -1)
- return (-1);
-
- ber_free(&al->ber);
- free(al);
-
- return (0);
-}
-
-struct aldap *
-aldap_init(int fd)
-{
- struct aldap *a;
-
- if ((a = calloc(1, sizeof(*a))) == NULL)
- return NULL;
- a->ber.fd = fd;
-
- return a;
-}
-
-int
-aldap_bind(struct aldap *ldap, char *binddn, char *bindcred)
-{
- struct ber_element *root = NULL, *elm;
- int error;
-
- if (binddn == NULL)
- binddn = "";
- if (bindcred == NULL)
- bindcred = "";
-
- if ((root = ber_add_sequence(NULL)) == NULL)
- goto fail;
-
- elm = ber_printf_elements(root, "d{tdsst", ++ldap->msgid, BER_CLASS_APP,
- (unsigned long)LDAP_REQ_BIND, ALDAP_VERSION, binddn, bindcred,
- BER_CLASS_CONTEXT, (unsigned long)LDAP_AUTH_SIMPLE);
- if (elm == NULL)
- goto fail;
-
- LDAP_DEBUG("aldap_bind", root);
-
- error = ber_write_elements(&ldap->ber, root);
- ber_free_elements(root);
- root = NULL;
- if (error == -1)
- goto fail;
-
- return (ldap->msgid);
-fail:
- if (root != NULL)
- ber_free_elements(root);
-
- ldap->err = ALDAP_ERR_OPERATION_FAILED;
- return (-1);
-}
-
-int
-aldap_unbind(struct aldap *ldap)
-{
- struct ber_element *root = NULL, *elm;
- int error;
-
- if ((root = ber_add_sequence(NULL)) == NULL)
- goto fail;
- elm = ber_printf_elements(root, "d{t", ++ldap->msgid, BER_CLASS_APP,
- LDAP_REQ_UNBIND_30);
- if (elm == NULL)
- goto fail;
-
- LDAP_DEBUG("aldap_unbind", root);
-
- error = ber_write_elements(&ldap->ber, root);
- ber_free_elements(root);
- root = NULL;
- if (error == -1)
- goto fail;
-
- return (ldap->msgid);
-fail:
- if (root != NULL)
- ber_free_elements(root);
-
- ldap->err = ALDAP_ERR_OPERATION_FAILED;
-
- return (-1);
-}
-
-int
-aldap_search(struct aldap *ldap, char *basedn, enum scope scope, char *filter,
- char **attrs, int typesonly, int sizelimit, int timelimit,
- struct aldap_page_control *page)
-{
- struct ber_element *root = NULL, *ber, *c;
- int i, error;
-
- if ((root = ber_add_sequence(NULL)) == NULL)
- goto fail;
-
- ber = ber_printf_elements(root, "d{t", ++ldap->msgid, BER_CLASS_APP,
- (unsigned long) LDAP_REQ_SEARCH);
- if (ber == NULL) {
- ldap->err = ALDAP_ERR_OPERATION_FAILED;
- goto fail;
- }
-
- c = ber;
- ber = ber_printf_elements(ber, "sEEddb", basedn, (long long)scope,
- (long long)LDAP_DEREF_NEVER, sizelimit,
- timelimit, typesonly);
- if (ber == NULL) {
- ldap->err = ALDAP_ERR_OPERATION_FAILED;
- goto fail;
- }
-
- if ((ber = ldap_parse_search_filter(ber, filter)) == NULL) {
- ldap->err = ALDAP_ERR_PARSER_ERROR;
- goto fail;
- }
-
- if ((ber = ber_add_sequence(ber)) == NULL)
- goto fail;
- if (attrs != NULL)
- for (i = 0; attrs[i] != NULL; i++) {
- if ((ber = ber_add_string(ber, attrs[i])) == NULL)
- goto fail;
- }
-
- aldap_create_page_control(c, 100, page);
-
- LDAP_DEBUG("aldap_search", root);
-
- error = ber_write_elements(&ldap->ber, root);
- ber_free_elements(root);
- root = NULL;
- if (error == -1) {
- ldap->err = ALDAP_ERR_OPERATION_FAILED;
- goto fail;
- }
-
- return (ldap->msgid);
-
-fail:
- if (root != NULL)
- ber_free_elements(root);
-
- return (-1);
-}
-
-int
-aldap_create_page_control(struct ber_element *elm, int size,
- struct aldap_page_control *page)
-{
- int len;
- struct ber c;
- struct ber_element *ber = NULL;
-
- c.br_wbuf = NULL;
- c.fd = -1;
-
- ber = ber_add_sequence(NULL);
-
- if (page == NULL) {
- if (ber_printf_elements(ber, "ds", 50, "") == NULL)
- goto fail;
- } else {
- if (ber_printf_elements(ber, "dx", 50, page->cookie,
- page->cookie_len) == NULL)
- goto fail;
- }
-
- if ((len = ber_write_elements(&c, ber)) < 1)
- goto fail;
- if (ber_printf_elements(elm, "{t{sx", 2, 0, LDAP_PAGED_OID,
- c.br_wbuf, (size_t)len) == NULL)
- goto fail;
-
- ber_free_elements(ber);
- ber_free(&c);
- return len;
-fail:
- if (ber != NULL)
- ber_free_elements(ber);
- ber_free(&c);
-
- return (-1);
-}
-
-struct aldap_message *
-aldap_parse(struct aldap *ldap)
-{
- int class;
- unsigned long type;
- long long msgid = 0;
- struct aldap_message *m;
- struct ber_element *a = NULL, *ep;
-
- if ((m = calloc(1, sizeof(struct aldap_message))) == NULL)
- return NULL;
-
- if ((m->msg = ber_read_elements(&ldap->ber, NULL)) == NULL)
- goto parsefail;
-
- LDAP_DEBUG("message", m->msg);
-
- if (ber_scanf_elements(m->msg, "{ite", &msgid, &class, &type, &a) != 0)
- goto parsefail;
- m->msgid = msgid;
- m->message_type = type;
- m->protocol_op = a;
-
- switch (m->message_type) {
- case LDAP_RES_BIND:
- case LDAP_RES_MODIFY:
- case LDAP_RES_ADD:
- case LDAP_RES_DELETE:
- case LDAP_RES_MODRDN:
- case LDAP_RES_COMPARE:
- case LDAP_RES_SEARCH_RESULT:
- if (ber_scanf_elements(m->protocol_op, "{EeSeSe",
- &m->body.res.rescode, &m->dn, &m->body.res.diagmsg, &a) != 0)
- goto parsefail;
- if (m->body.res.rescode == LDAP_REFERRAL)
- if (ber_scanf_elements(a, "{e", &m->references) != 0)
- goto parsefail;
- if (m->msg->be_sub) {
- for (ep = m->msg->be_sub; ep != NULL; ep = ep->be_next) {
- ber_scanf_elements(ep, "t", &class, &type);
- if (class == 2 && type == 0)
- m->page = aldap_parse_page_control(ep->be_sub->be_sub,
- ep->be_sub->be_sub->be_len);
- }
- } else
- m->page = NULL;
- break;
- case LDAP_RES_SEARCH_ENTRY:
- if (ber_scanf_elements(m->protocol_op, "{eS{e", &m->dn,
- &m->body.search.attrs) != 0)
- goto parsefail;
- break;
- case LDAP_RES_SEARCH_REFERENCE:
- if (ber_scanf_elements(m->protocol_op, "{e", &m->references) != 0)
- goto parsefail;
- break;
- }
-
- return m;
-parsefail:
- ldap->err = ALDAP_ERR_PARSER_ERROR;
- aldap_freemsg(m);
- return NULL;
-}
-
-struct aldap_page_control *
-aldap_parse_page_control(struct ber_element *control, size_t len)
-{
- char *oid, *s;
- char *encoded;
- struct ber b;
- struct ber_element *elm;
- struct aldap_page_control *page;
-
- b.br_wbuf = NULL;
- b.fd = -1;
- ber_scanf_elements(control, "ss", &oid, &encoded);
- ber_set_readbuf(&b, encoded, control->be_next->be_len);
- elm = ber_read_elements(&b, NULL);
- if (elm == NULL) {
- ber_free(&b);
- return NULL;
- }
-
- if ((page = malloc(sizeof(struct aldap_page_control))) == NULL) {
- ber_free_elements(elm);
- ber_free(&b);
- return NULL;
- }
-
- ber_scanf_elements(elm->be_sub, "is", &page->size, &s);
- page->cookie_len = elm->be_sub->be_next->be_len;
-
- if ((page->cookie = malloc(page->cookie_len)) == NULL) {
- ber_free_elements(elm);
- ber_free(&b);
- free(page);
- return NULL;
- }
- memcpy(page->cookie, s, page->cookie_len);
-
- ber_free_elements(elm);
- ber_free(&b);
- return page;
-}
-
-void
-aldap_freepage(struct aldap_page_control *page)
-{
- if (page->cookie)
- free(page->cookie);
- free(page);
-}
-
-void
-aldap_freemsg(struct aldap_message *msg)
-{
- if (msg->msg)
- ber_free_elements(msg->msg);
- free(msg);
-}
-
-int
-aldap_get_resultcode(struct aldap_message *msg)
-{
- return msg->body.res.rescode;
-}
-
-char *
-aldap_get_dn(struct aldap_message *msg)
-{
- char *dn;
-
- if (msg->dn == NULL)
- return NULL;
-
- if (ber_get_string(msg->dn, &dn) == -1)
- return NULL;
-
- return utoa(dn);
-}
-
-char **
-aldap_get_references(struct aldap_message *msg)
-{
- if (msg->references == NULL)
- return NULL;
- return aldap_get_stringset(msg->references);
-}
-
-void
-aldap_free_references(char **values)
-{
- int i;
-
- if (values == NULL)
- return;
-
- for (i = 0; values[i] != NULL; i++)
- free(values[i]);
-
- free(values);
-}
-
-char *
-aldap_get_diagmsg(struct aldap_message *msg)
-{
- char *s;
-
- if (msg->body.res.diagmsg == NULL)
- return NULL;
-
- if (ber_get_string(msg->body.res.diagmsg, &s) == -1)
- return NULL;
-
- return utoa(s);
-}
-
-int
-aldap_count_attrs(struct aldap_message *msg)
-{
- int i;
- struct ber_element *a;
-
- if (msg->body.search.attrs == NULL)
- return (-1);
-
- for (i = 0, a = msg->body.search.attrs;
- a != NULL && ber_get_eoc(a) != 0;
- i++, a = a->be_next)
- ;
-
- return i;
-}
-
-int
-aldap_first_attr(struct aldap_message *msg, char **outkey, char ***outvalues)
-{
- struct ber_element *b, *c;
- char *key;
- char **ret;
-
- if (msg->body.search.attrs == NULL)
- goto fail;
-
- if (ber_scanf_elements(msg->body.search.attrs, "{s(e)}e",
- &key, &b, &c) != 0)
- goto fail;
-
- msg->body.search.iter = msg->body.search.attrs->be_next;
-
- if ((ret = aldap_get_stringset(b)) == NULL)
- goto fail;
-
- (*outvalues) = ret;
- (*outkey) = utoa(key);
-
- return (1);
-fail:
- (*outkey) = NULL;
- (*outvalues) = NULL;
- return (-1);
-}
-
-int
-aldap_next_attr(struct aldap_message *msg, char **outkey, char ***outvalues)
-{
- struct ber_element *a, *b;
- char *key;
- char **ret;
-
- if (msg->body.search.iter == NULL)
- goto notfound;
-
- LDAP_DEBUG("attr", msg->body.search.iter);
-
- if (ber_get_eoc(msg->body.search.iter) == 0)
- goto notfound;
-
- if (ber_scanf_elements(msg->body.search.iter, "{s(e)}e", &key, &a, &b)
- != 0)
- goto fail;
-
- msg->body.search.iter = msg->body.search.iter->be_next;
-
- if ((ret = aldap_get_stringset(a)) == NULL)
- goto fail;
-
- (*outvalues) = ret;
- (*outkey) = utoa(key);
-
- return (1);
-fail:
-notfound:
- (*outkey) = NULL;
- (*outvalues) = NULL;
- return (-1);
-}
-
-int
-aldap_match_attr(struct aldap_message *msg, char *inkey, char ***outvalues)
-{
- struct ber_element *a, *b;
- char *descr = NULL;
- char **ret;
-
- if (msg->body.search.attrs == NULL)
- goto fail;
-
- LDAP_DEBUG("attr", msg->body.search.attrs);
-
- for (a = msg->body.search.attrs;;) {
- if (a == NULL)
- goto notfound;
- if (ber_get_eoc(a) == 0)
- goto notfound;
- if (ber_scanf_elements(a, "{s(e", &descr, &b) != 0)
- goto fail;
- if (strcasecmp(descr, inkey) == 0)
- goto attrfound;
- a = a->be_next;
- }
-
-attrfound:
- if ((ret = aldap_get_stringset(b)) == NULL)
- goto fail;
-
- (*outvalues) = ret;
-
- return (1);
-fail:
-notfound:
- (*outvalues) = NULL;
- return (-1);
-}
-
-int
-aldap_free_attr(char **values)
-{
- int i;
-
- if (values == NULL)
- return -1;
-
- for (i = 0; values[i] != NULL; i++)
- free(values[i]);
-
- free(values);
-
- return (1);
-}
-
-void
-aldap_free_url(struct aldap_url *lu)
-{
- free(lu->buffer);
- free(lu->filter);
-}
-
-int
-aldap_parse_url(char *url, struct aldap_url *lu)
-{
- char *p, *forward, *forward2;
- const char *errstr = NULL;
- int i;
-
- if ((lu->buffer = strdup(url)) == NULL)
- return (-1);
- p = lu->buffer;
-
- /* protocol */
- if (strncasecmp(LDAP_URL, p, strlen(LDAP_URL)) != 0)
- goto fail;
- lu->protocol = LDAP;
- p += strlen(LDAP_URL);
-
- /* host and optional port */
- if ((forward = strchr(p, '/')) != NULL)
- *forward = '\0';
- /* find the optional port */
- if ((forward2 = strchr(p, ':')) != NULL) {
- *forward2 = '\0';
- /* if a port is given */
- if (*(forward2+1) != '\0') {
-#define PORT_MAX UINT16_MAX
- lu->port = strtonum(++forward2, 0, PORT_MAX, &errstr);
- if (errstr)
- goto fail;
- }
- } else {
- lu->port = LDAP_PORT;
- }
- /* fail if no host is given */
- if (strlen(p) == 0)
- goto fail;
- lu->host = p;
- if (forward == NULL)
- goto done;
- /* p is assigned either a pointer to a character or to '\0' */
- p = ++forward;
- if (strlen(p) == 0)
- goto done;
-
- /* dn */
- if ((forward = strchr(p, '?')) != NULL)
- *forward = '\0';
- lu->dn = p;
- if (forward == NULL)
- goto done;
- /* p is assigned either a pointer to a character or to '\0' */
- p = ++forward;
- if (strlen(p) == 0)
- goto done;
-
- /* attributes */
- if ((forward = strchr(p, '?')) != NULL)
- *forward = '\0';
- for (i = 0; i < MAXATTR; i++) {
- if ((forward2 = strchr(p, ',')) == NULL) {
- if (strlen(p) == 0)
- break;
- lu->attributes[i] = p;
- break;
- }
- *forward2 = '\0';
- lu->attributes[i] = p;
- p = ++forward2;
- }
- if (forward == NULL)
- goto done;
- /* p is assigned either a pointer to a character or to '\0' */
- p = ++forward;
- if (strlen(p) == 0)
- goto done;
-
- /* scope */
- if ((forward = strchr(p, '?')) != NULL)
- *forward = '\0';
- if (strcmp(p, "base") == 0)
- lu->scope = LDAP_SCOPE_BASE;
- else if (strcmp(p, "one") == 0)
- lu->scope = LDAP_SCOPE_ONELEVEL;
- else if (strcmp(p, "sub") == 0)
- lu->scope = LDAP_SCOPE_SUBTREE;
- else
- goto fail;
- if (forward == NULL)
- goto done;
- p = ++forward;
- if (strlen(p) == 0)
- goto done;
-
- /* filter */
- if (p)
- lu->filter = p;
-done:
- free(url);
- return (1);
-fail:
- free(lu->buffer);
- lu->buffer = NULL;
- return (-1);
-}
-
-#if 0
-int
-aldap_search_url(struct aldap *ldap, char *url, int typesonly, int sizelimit,
- int timelimit)
-{
- struct aldap_url *lu;
-
- if ((lu = calloc(1, sizeof(*lu))) == NULL)
- return (-1);
-
- if (aldap_parse_url(url, lu))
- goto fail;
-
- if (aldap_search(ldap, lu->dn, lu->scope, lu->filter, lu->attributes,
- typesonly, sizelimit, timelimit) == -1)
- goto fail;
-
- aldap_free_url(lu);
- return (ldap->msgid);
-fail:
- aldap_free_url(lu);
- return (-1);
-}
-#endif
-
-/*
- * internal functions
- */
-
-char **
-aldap_get_stringset(struct ber_element *elm)
-{
- struct ber_element *a;
- int i;
- char **ret;
- char *s;
-
- if (elm->be_type != BER_TYPE_OCTETSTRING)
- return NULL;
-
- for (a = elm, i = 1; i > 0 && a != NULL && a->be_type ==
- BER_TYPE_OCTETSTRING; a = a->be_next, i++)
- ;
- if (i == 1)
- return NULL;
-
- if ((ret = calloc(i + 1, sizeof(char *))) == NULL)
- return NULL;
-
- for (a = elm, i = 0; a != NULL && a->be_type == BER_TYPE_OCTETSTRING;
- a = a->be_next, i++) {
-
- ber_get_string(a, &s);
- ret[i] = utoa(s);
- }
- ret[i + 1] = NULL;
-
- return ret;
-}
-
-/*
- * Base case for ldap_do_parse_search_filter
- *
- * returns:
- * struct ber_element *, ber_element tree
- * NULL, parse failed
- */
-static struct ber_element *
-ldap_parse_search_filter(struct ber_element *ber, char *filter)
-{
- struct ber_element *elm;
- char *cp;
-
- cp = filter;
-
- if (cp == NULL || *cp == '\0') {
- errno = EINVAL;
- return (NULL);
- }
-
- if ((elm = ldap_do_parse_search_filter(ber, &cp)) == NULL)
- return (NULL);
-
- if (*cp != '\0') {
- ber_free_elements(elm);
- ber_link_elements(ber, NULL);
- errno = EINVAL;
- return (NULL);
- }
-
- return (elm);
-}
-
-/*
- * Translate RFC4515 search filter string into ber_element tree
- *
- * returns:
- * struct ber_element *, ber_element tree
- * NULL, parse failed
- *
- * notes:
- * when cp is passed to a recursive invocation, it is updated
- * to point one character beyond the filter that was passed
- * i.e., cp jumps to "(filter)" upon return
- * ^
- * goto's used to discriminate error-handling based on error type
- * doesn't handle extended filters (yet)
- *
- */
-static struct ber_element *
-ldap_do_parse_search_filter(struct ber_element *prev, char **cpp)
-{
- struct ber_element *elm, *root = NULL;
- char *attr_desc, *attr_val, *parsed_val, *cp;
- size_t len;
- unsigned long type;
-
- root = NULL;
-
- /* cpp should pass in pointer to opening parenthesis of "(filter)" */
- cp = *cpp;
- if (*cp != '(')
- goto syntaxfail;
-
- switch (*++cp) {
- case '&': /* AND */
- case '|': /* OR */
- if (*cp == '&')
- type = LDAP_FILT_AND;
- else
- type = LDAP_FILT_OR;
-
- if ((elm = ber_add_set(prev)) == NULL)
- goto callfail;
- root = elm;
- ber_set_header(elm, BER_CLASS_CONTEXT, type);
-
- if (*++cp != '(') /* opening `(` of filter */
- goto syntaxfail;
-
- while (*cp == '(') {
- if ((elm =
- ldap_do_parse_search_filter(elm, &cp)) == NULL)
- goto bad;
- }
-
- if (*cp != ')') /* trailing `)` of filter */
- goto syntaxfail;
- break;
-
- case '!': /* NOT */
- if ((root = ber_add_sequence(prev)) == NULL)
- goto callfail;
- ber_set_header(root, BER_CLASS_CONTEXT, LDAP_FILT_NOT);
-
- cp++; /* now points to sub-filter */
- if (ldap_do_parse_search_filter(root, &cp) == NULL)
- goto bad;
-
- if (*cp != ')') /* trailing `)` of filter */
- goto syntaxfail;
- break;
-
- default: /* SIMPLE || PRESENCE */
- attr_desc = cp;
-
- len = strcspn(cp, "()<>~=");
- cp += len;
- switch (*cp) {
- case '~':
- type = LDAP_FILT_APPR;
- cp++;
- break;
- case '<':
- type = LDAP_FILT_LE;
- cp++;
- break;
- case '>':
- type = LDAP_FILT_GE;
- cp++;
- break;
- case '=':
- type = LDAP_FILT_EQ; /* assume EQ until disproven */
- break;
- case '(':
- case ')':
- default:
- goto syntaxfail;
- }
- attr_val = ++cp;
-
- /* presence filter */
- if (strncmp(attr_val, "*)", 2) == 0) {
- cp++; /* point to trailing `)` */
- if ((root =
- ber_add_nstring(prev, attr_desc, len)) == NULL)
- goto bad;
-
- ber_set_header(root, BER_CLASS_CONTEXT, LDAP_FILT_PRES);
- break;
- }
-
- if ((root = ber_add_sequence(prev)) == NULL)
- goto callfail;
- ber_set_header(root, BER_CLASS_CONTEXT, type);
-
- if ((elm = ber_add_nstring(root, attr_desc, len)) == NULL)
- goto callfail;
-
- len = strcspn(attr_val, "*)");
- if (len == 0 && *cp != '*')
- goto syntaxfail;
- cp += len;
- if (*cp == '\0')
- goto syntaxfail;
-
- if (*cp == '*') { /* substring filter */
- int initial;
-
- cp = attr_val;
-
- ber_set_header(root, BER_CLASS_CONTEXT, LDAP_FILT_SUBS);
-
- if ((elm = ber_add_sequence(elm)) == NULL)
- goto callfail;
-
- for (initial = 1;; cp++, initial = 0) {
- attr_val = cp;
-
- len = strcspn(attr_val, "*)");
- if (len == 0) {
- if (*cp == ')')
- break;
- else
- continue;
- }
- cp += len;
- if (*cp == '\0')
- goto syntaxfail;
-
- if (initial)
- type = LDAP_FILT_SUBS_INIT;
- else if (*cp == ')')
- type = LDAP_FILT_SUBS_FIN;
- else
- type = LDAP_FILT_SUBS_ANY;
-
- if ((parsed_val = parseval(attr_val, len)) ==
- NULL)
- goto callfail;
- elm = ber_add_nstring(elm, parsed_val,
- strlen(parsed_val));
- free(parsed_val);
- if (elm == NULL)
- goto callfail;
- ber_set_header(elm, BER_CLASS_CONTEXT, type);
- if (type == LDAP_FILT_SUBS_FIN)
- break;
- }
- break;
- }
-
- if ((parsed_val = parseval(attr_val, len)) == NULL)
- goto callfail;
- elm = ber_add_nstring(elm, parsed_val, strlen(parsed_val));
- free(parsed_val);
- if (elm == NULL)
- goto callfail;
- break;
- }
-
- cp++; /* now points one char beyond the trailing `)` */
-
- *cpp = cp;
- return (root);
-
-syntaxfail: /* XXX -- error reporting */
-callfail:
-bad:
- if (root != NULL)
- ber_free_elements(root);
- ber_link_elements(prev, NULL);
- return (NULL);
-}
-
-#ifdef DEBUG
-/*
- * Display a list of ber elements.
- *
- */
-void
-ldap_debug_elements(struct ber_element *root)
-{
- static int indent = 0;
- long long v;
- int d;
- char *buf;
- size_t len;
- unsigned int i;
- int constructed;
- struct ber_oid o;
-
- /* calculate lengths */
- ber_calc_len(root);
-
- switch (root->be_encoding) {
- case BER_TYPE_SEQUENCE:
- case BER_TYPE_SET:
- constructed = root->be_encoding;
- break;
- default:
- constructed = 0;
- break;
- }
-
- fprintf(stderr, "%*slen %lu ", indent, "", root->be_len);
- switch (root->be_class) {
- case BER_CLASS_UNIVERSAL:
- fprintf(stderr, "class: universal(%u) type: ", root->be_class);
- switch (root->be_type) {
- case BER_TYPE_EOC:
- fprintf(stderr, "end-of-content");
- break;
- case BER_TYPE_BOOLEAN:
- fprintf(stderr, "boolean");
- break;
- case BER_TYPE_INTEGER:
- fprintf(stderr, "integer");
- break;
- case BER_TYPE_BITSTRING:
- fprintf(stderr, "bit-string");
- break;
- case BER_TYPE_OCTETSTRING:
- fprintf(stderr, "octet-string");
- break;
- case BER_TYPE_NULL:
- fprintf(stderr, "null");
- break;
- case BER_TYPE_OBJECT:
- fprintf(stderr, "object");
- break;
- case BER_TYPE_ENUMERATED:
- fprintf(stderr, "enumerated");
- break;
- case BER_TYPE_SEQUENCE:
- fprintf(stderr, "sequence");
- break;
- case BER_TYPE_SET:
- fprintf(stderr, "set");
- break;
- }
- break;
- case BER_CLASS_APPLICATION:
- fprintf(stderr, "class: application(%u) type: ",
- root->be_class);
- switch (root->be_type) {
- case LDAP_REQ_BIND:
- fprintf(stderr, "bind");
- break;
- case LDAP_RES_BIND:
- fprintf(stderr, "bind");
- break;
- case LDAP_REQ_UNBIND_30:
- break;
- case LDAP_REQ_SEARCH:
- fprintf(stderr, "search");
- break;
- case LDAP_RES_SEARCH_ENTRY:
- fprintf(stderr, "search_entry");
- break;
- case LDAP_RES_SEARCH_RESULT:
- fprintf(stderr, "search_result");
- break;
- case LDAP_REQ_MODIFY:
- fprintf(stderr, "modify");
- break;
- case LDAP_RES_MODIFY:
- fprintf(stderr, "modify");
- break;
- case LDAP_REQ_ADD:
- fprintf(stderr, "add");
- break;
- case LDAP_RES_ADD:
- fprintf(stderr, "add");
- break;
- case LDAP_REQ_DELETE_30:
- fprintf(stderr, "delete");
- break;
- case LDAP_RES_DELETE:
- fprintf(stderr, "delete");
- break;
- case LDAP_REQ_MODRDN:
- fprintf(stderr, "modrdn");
- break;
- case LDAP_RES_MODRDN:
- fprintf(stderr, "modrdn");
- break;
- case LDAP_REQ_COMPARE:
- fprintf(stderr, "compare");
- break;
- case LDAP_RES_COMPARE:
- fprintf(stderr, "compare");
- break;
- case LDAP_REQ_ABANDON_30:
- fprintf(stderr, "abandon");
- break;
- }
- break;
- case BER_CLASS_PRIVATE:
- fprintf(stderr, "class: private(%u) type: ", root->be_class);
- fprintf(stderr, "encoding (%lu) type: ", root->be_encoding);
- break;
- case BER_CLASS_CONTEXT:
- /* XXX: this is not correct */
- fprintf(stderr, "class: context(%u) type: ", root->be_class);
- switch(root->be_type) {
- case LDAP_AUTH_SIMPLE:
- fprintf(stderr, "auth simple");
- break;
- }
- break;
- default:
- fprintf(stderr, "class: <INVALID>(%u) type: ", root->be_class);
- break;
- }
- fprintf(stderr, "(%lu) encoding %lu ",
- root->be_type, root->be_encoding);
-
- if (constructed)
- root->be_encoding = constructed;
-
- switch (root->be_encoding) {
- case BER_TYPE_BOOLEAN:
- if (ber_get_boolean(root, &d) == -1) {
- fprintf(stderr, "<INVALID>\n");
- break;
- }
- fprintf(stderr, "%s(%d)\n", d ? "true" : "false", d);
- break;
- case BER_TYPE_INTEGER:
- if (ber_get_integer(root, &v) == -1) {
- fprintf(stderr, "<INVALID>\n");
- break;
- }
- fprintf(stderr, "value %lld\n", v);
- break;
- case BER_TYPE_ENUMERATED:
- if (ber_get_enumerated(root, &v) == -1) {
- fprintf(stderr, "<INVALID>\n");
- break;
- }
- fprintf(stderr, "value %lld\n", v);
- break;
- case BER_TYPE_BITSTRING:
- if (ber_get_bitstring(root, (void *)&buf, &len) == -1) {
- fprintf(stderr, "<INVALID>\n");
- break;
- }
- fprintf(stderr, "hexdump ");
- for (i = 0; i < len; i++)
- fprintf(stderr, "%02x", buf[i]);
- fprintf(stderr, "\n");
- break;
- case BER_TYPE_OBJECT:
- if (ber_get_oid(root, &o) == -1) {
- fprintf(stderr, "<INVALID>\n");
- break;
- }
- fprintf(stderr, "\n");
- break;
- case BER_TYPE_OCTETSTRING:
- if (ber_get_nstring(root, (void *)&buf, &len) == -1) {
- fprintf(stderr, "<INVALID>\n");
- break;
- }
- fprintf(stderr, "string \"%.*s\"\n", len, buf);
- break;
- case BER_TYPE_NULL: /* no payload */
- case BER_TYPE_EOC:
- case BER_TYPE_SEQUENCE:
- case BER_TYPE_SET:
- default:
- fprintf(stderr, "\n");
- break;
- }
-
- if (constructed && root->be_sub) {
- indent += 2;
- ldap_debug_elements(root->be_sub);
- indent -= 2;
- }
- if (root->be_next)
- ldap_debug_elements(root->be_next);
-}
-#endif
-
-/*
- * Convert UTF-8 to ASCII.
- * notes:
- * non-ASCII characters are displayed as '?'
- * the argument u should be a NULL terminated sequence of UTF-8 bytes.
- */
-char *
-utoa(char *u)
-{
- int len, i, j;
- char *str;
-
- /* calculate the length to allocate */
- for (len = 0, i = 0; u[i] != '\0'; ) {
- if ((u[i] & 0xF0) == 0xF0)
- i += 4;
- else if ((u[i] & 0xE0) == 0xE0)
- i += 3;
- else if ((u[i] & 0xC0) == 0xC0)
- i += 2;
- else
- i += 1;
- len++;
- }
-
- if ((str = calloc(len + 1, sizeof(char))) == NULL)
- return NULL;
-
- /* copy the ASCII characters to the newly allocated string */
- for (i = 0, j = 0; u[i] != '\0'; j++) {
- if ((u[i] & 0xF0) == 0xF0) {
- str[j] = '?';
- i += 4;
- } else if ((u[i] & 0xE0) == 0xE0) {
- str[j] = '?';
- i += 3;
- } else if ((u[i] & 0xC0) == 0xC0) {
- str[j] = '?';
- i += 2;
- } else {
- str[j] = u[i];
- i += 1;
- }
- }
-
- return str;
-}
-
-/*
- * Parse a LDAP value
- * notes:
- * the argument u should be a NULL terminated sequence of ASCII bytes.
- */
-char *
-parseval(char *p, size_t len)
-{
- char hex[3];
- char *cp = p, *buffer, *newbuffer;
- size_t size, newsize, i, j;
-
- size = 50;
- if ((buffer = calloc(1, size)) == NULL)
- return NULL;
-
- for (i = j = 0; j < len; i++) {
- if (i >= size) {
- newsize = size + 1024;
- if ((newbuffer = realloc(buffer, newsize)) == NULL) {
- free(buffer);
- return (NULL);
- }
- buffer = newbuffer;
- size = newsize;
- }
-
- if (cp[j] == '\\') {
- (void)strlcpy(hex, cp + j + 1, sizeof(hex));
- buffer[i] = (char)strtoumax(hex, NULL, 16);
- j += 3;
- } else {
- buffer[i] = cp[j];
- j++;
- }
- }
-
- return buffer;
-}
-
-int
-aldap_get_errno(struct aldap *a, const char **estr)
-{
- switch (a->err) {
- case ALDAP_ERR_SUCCESS:
- *estr = "success";
- break;
- case ALDAP_ERR_PARSER_ERROR:
- *estr = "parser failed";
- break;
- case ALDAP_ERR_INVALID_FILTER:
- *estr = "invalid filter";
- break;
- case ALDAP_ERR_OPERATION_FAILED:
- *estr = "operation failed";
- break;
- default:
- *estr = "unknown";
- break;
- }
- return (a->err);
-}
diff --git a/usr.sbin/smtpd/aldap.h b/usr.sbin/smtpd/aldap.h
deleted file mode 100644
index 0793613346e..00000000000
--- a/usr.sbin/smtpd/aldap.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* $OpenBSD: aldap.h,v 1.6 2015/11/05 12:35:58 jung Exp $ */
-
-/*
- * Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org>
- * Copyright (c) 2006, 2007 Marc Balmer <mbalmer@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 "ber.h"
-
-#define LDAP_URL "ldap://"
-#define LDAP_PORT 389
-#define LDAP_PAGED_OID "1.2.840.113556.1.4.319"
-
-struct aldap {
-#define ALDAP_ERR_SUCCESS 0
-#define ALDAP_ERR_PARSER_ERROR 1
-#define ALDAP_ERR_INVALID_FILTER 2
-#define ALDAP_ERR_OPERATION_FAILED 3
- uint8_t err;
- int msgid;
- struct ber ber;
-};
-
-struct aldap_page_control {
- int size;
- char *cookie;
- unsigned int cookie_len;
-};
-
-struct aldap_message {
- int msgid;
- int message_type;
-
- struct ber_element *msg;
-
- struct ber_element *header;
- struct ber_element *protocol_op;
-
- struct ber_element *dn;
-
- union {
- struct {
- long long rescode;
- struct ber_element *diagmsg;
- } res;
- struct {
- struct ber_element *iter;
- struct ber_element *attrs;
- } search;
- } body;
- struct ber_element *references;
- struct aldap_page_control *page;
-};
-
-enum aldap_protocol {
- LDAP,
- LDAPS
-};
-
-struct aldap_url {
- int protocol;
- char *host;
- in_port_t port;
- char *dn;
-#define MAXATTR 1024
- char *attributes[MAXATTR];
- int scope;
- char *filter;
- char *buffer;
-};
-
-enum protocol_op {
- LDAP_REQ_BIND = 0,
- LDAP_RES_BIND = 1,
- LDAP_REQ_UNBIND_30 = 2,
- LDAP_REQ_SEARCH = 3,
- LDAP_RES_SEARCH_ENTRY = 4,
- LDAP_RES_SEARCH_RESULT = 5,
- LDAP_REQ_MODIFY = 6,
- LDAP_RES_MODIFY = 7,
- LDAP_REQ_ADD = 8,
- LDAP_RES_ADD = 9,
- LDAP_REQ_DELETE_30 = 10,
- LDAP_RES_DELETE = 11,
- LDAP_REQ_MODRDN = 12,
- LDAP_RES_MODRDN = 13,
- LDAP_REQ_COMPARE = 14,
- LDAP_RES_COMPARE = 15,
- LDAP_REQ_ABANDON_30 = 16,
-
- LDAP_RES_SEARCH_REFERENCE = 19,
-};
-
-enum deref_aliases {
- LDAP_DEREF_NEVER = 0,
- LDAP_DEREF_SEARCHING = 1,
- LDAP_DEREF_FINDING = 2,
- LDAP_DEREF_ALWAYS = 3,
-};
-
-enum authentication_choice {
- LDAP_AUTH_SIMPLE = 0,
-};
-
-enum scope {
- LDAP_SCOPE_BASE = 0,
- LDAP_SCOPE_ONELEVEL = 1,
- LDAP_SCOPE_SUBTREE = 2,
-};
-
-enum result_code {
- LDAP_SUCCESS = 0,
- LDAP_OPERATIONS_ERROR = 1,
- LDAP_PROTOCOL_ERROR = 2,
- LDAP_TIMELIMIT_EXCEEDED = 3,
- LDAP_SIZELIMIT_EXCEEDED = 4,
- LDAP_COMPARE_FALSE = 5,
- LDAP_COMPARE_TRUE = 6,
- LDAP_STRONG_AUTH_NOT_SUPPORTED = 7,
- LDAP_STRONG_AUTH_REQUIRED = 8,
-
- LDAP_REFERRAL = 10,
- LDAP_ADMINLIMIT_EXCEEDED = 11,
- LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12,
- LDAP_CONFIDENTIALITY_REQUIRED = 13,
- LDAP_SASL_BIND_IN_PROGRESS = 14,
- LDAP_NO_SUCH_ATTRIBUTE = 16,
- LDAP_UNDEFINED_TYPE = 17,
- LDAP_INAPPROPRIATE_MATCHING = 18,
- LDAP_CONSTRAINT_VIOLATION = 19,
- LDAP_TYPE_OR_VALUE_EXISTS = 20,
- LDAP_INVALID_SYNTAX = 21,
-
- LDAP_NO_SUCH_OBJECT = 32,
- LDAP_ALIAS_PROBLEM = 33,
- LDAP_INVALID_DN_SYNTAX = 34,
-
- LDAP_ALIAS_DEREF_PROBLEM = 36,
-
- LDAP_INAPPROPRIATE_AUTH = 48,
- LDAP_INVALID_CREDENTIALS = 49,
- LDAP_INSUFFICIENT_ACCESS = 50,
- LDAP_BUSY = 51,
- LDAP_UNAVAILABLE = 52,
- LDAP_UNWILLING_TO_PERFORM = 53,
- LDAP_LOOP_DETECT = 54,
-
- LDAP_NAMING_VIOLATION = 64,
- LDAP_OBJECT_CLASS_VIOLATION = 65,
- LDAP_NOT_ALLOWED_ON_NONLEAF = 66,
- LDAP_NOT_ALLOWED_ON_RDN = 67,
- LDAP_ALREADY_EXISTS = 68,
- LDAP_NO_OBJECT_CLASS_MODS = 69,
-
- LDAP_AFFECTS_MULTIPLE_DSAS = 71,
-
- LDAP_OTHER = 80,
-};
-
-enum ldap_filter {
- LDAP_FILT_AND = 0,
- LDAP_FILT_OR = 1,
- LDAP_FILT_NOT = 2,
- LDAP_FILT_EQ = 3,
- LDAP_FILT_SUBS = 4,
- LDAP_FILT_GE = 5,
- LDAP_FILT_LE = 6,
- LDAP_FILT_PRES = 7,
- LDAP_FILT_APPR = 8,
-};
-
-enum ldap_subfilter {
- LDAP_FILT_SUBS_INIT = 0,
- LDAP_FILT_SUBS_ANY = 1,
- LDAP_FILT_SUBS_FIN = 2,
-};
-
-struct aldap *aldap_init(int fd);
-int aldap_close(struct aldap *);
-struct aldap_message *aldap_parse(struct aldap *);
-void aldap_freemsg(struct aldap_message *);
-
-int aldap_bind(struct aldap *, char *, char *);
-int aldap_unbind(struct aldap *);
-int aldap_search(struct aldap *, char *, enum scope, char *, char **, int, int, int, struct aldap_page_control *);
-int aldap_get_errno(struct aldap *, const char **);
-
-int aldap_get_resultcode(struct aldap_message *);
-char *aldap_get_dn(struct aldap_message *);
-char *aldap_get_diagmsg(struct aldap_message *);
-char **aldap_get_references(struct aldap_message *);
-void aldap_free_references(char **values);
-int aldap_parse_url(char *, struct aldap_url *);
-void aldap_free_url(struct aldap_url *);
-#if 0
-int aldap_search_url(struct aldap *, char *, int, int, int);
-#endif
-
-int aldap_count_attrs(struct aldap_message *);
-int aldap_match_attr(struct aldap_message *, char *, char ***);
-int aldap_first_attr(struct aldap_message *, char **, char ***);
-int aldap_next_attr(struct aldap_message *, char **, char ***);
-int aldap_free_attr(char **);
-
-struct aldap_page_control *aldap_parse_page_control(struct ber_element *, size_t len);
-void aldap_freepage(struct aldap_page_control *);
diff --git a/usr.sbin/smtpd/ber.c b/usr.sbin/smtpd/ber.c
deleted file mode 100644
index e44fbe04791..00000000000
--- a/usr.sbin/smtpd/ber.c
+++ /dev/null
@@ -1,1269 +0,0 @@
-/* $OpenBSD: ber.c,v 1.8 2015/11/23 13:22:37 gilles Exp $ */
-
-/*
- * Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
- * Copyright (c) 2006, 2007 Claudio Jeker <claudio@openbsd.org>
- * Copyright (c) 2006, 2007 Marc Balmer <mbalmer@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 <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <err.h> /* XXX for debug output */
-#include <stdio.h> /* XXX for debug output */
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#include "ber.h"
-
-#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
-
-#define BER_TYPE_CONSTRUCTED 0x20 /* otherwise primitive */
-#define BER_TYPE_SINGLE_MAX 30
-#define BER_TAG_MASK 0x1f
-#define BER_TAG_MORE 0x80 /* more subsequent octets */
-#define BER_TAG_TYPE_MASK 0x7f
-#define BER_CLASS_SHIFT 6
-
-static int ber_dump_element(struct ber *ber, struct ber_element *root);
-static void ber_dump_header(struct ber *ber, struct ber_element *root);
-static void ber_putc(struct ber *ber, unsigned char c);
-static void ber_write(struct ber *ber, void *buf, size_t len);
-static ssize_t get_id(struct ber *b, unsigned long *tag, int *class,
- int *cstruct);
-static ssize_t get_len(struct ber *b, ssize_t *len);
-static ssize_t ber_read_element(struct ber *ber, struct ber_element *elm);
-static ssize_t ber_readbuf(struct ber *b, void *buf, size_t nbytes);
-static ssize_t ber_getc(struct ber *b, unsigned char *c);
-static ssize_t ber_read(struct ber *ber, void *buf, size_t len);
-
-#ifdef DEBUG
-#define DPRINTF(...) printf(__VA_ARGS__)
-#else
-#define DPRINTF(...) do { } while (0)
-#endif
-
-struct ber_element *
-ber_get_element(unsigned long encoding)
-{
- struct ber_element *elm;
-
- if ((elm = calloc(1, sizeof(*elm))) == NULL)
- return NULL;
-
- elm->be_encoding = encoding;
- ber_set_header(elm, BER_CLASS_UNIVERSAL, BER_TYPE_DEFAULT);
-
- return elm;
-}
-
-void
-ber_set_header(struct ber_element *elm, int class, unsigned long type)
-{
- elm->be_class = class & BER_CLASS_MASK;
- if (type == BER_TYPE_DEFAULT)
- type = elm->be_encoding;
- elm->be_type = type;
-}
-
-void
-ber_link_elements(struct ber_element *prev, struct ber_element *elm)
-{
- if (prev != NULL) {
- if ((prev->be_encoding == BER_TYPE_SEQUENCE ||
- prev->be_encoding == BER_TYPE_SET) &&
- prev->be_sub == NULL)
- prev->be_sub = elm;
- else
- prev->be_next = elm;
- }
-}
-
-struct ber_element *
-ber_unlink_elements(struct ber_element *prev)
-{
- struct ber_element *elm;
-
- if ((prev->be_encoding == BER_TYPE_SEQUENCE ||
- prev->be_encoding == BER_TYPE_SET) &&
- prev->be_sub != NULL) {
- elm = prev->be_sub;
- prev->be_sub = NULL;
- } else {
- elm = prev->be_next;
- prev->be_next = NULL;
- }
-
- return (elm);
-}
-
-void
-ber_replace_elements(struct ber_element *prev, struct ber_element *new)
-{
- struct ber_element *ber, *next;
-
- ber = ber_unlink_elements(prev);
- next = ber_unlink_elements(ber);
- ber_link_elements(new, next);
- ber_link_elements(prev, new);
-
- /* cleanup old element */
- ber_free_elements(ber);
-}
-
-struct ber_element *
-ber_add_sequence(struct ber_element *prev)
-{
- struct ber_element *elm;
-
- if ((elm = ber_get_element(BER_TYPE_SEQUENCE)) == NULL)
- return NULL;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-struct ber_element *
-ber_add_set(struct ber_element *prev)
-{
- struct ber_element *elm;
-
- if ((elm = ber_get_element(BER_TYPE_SET)) == NULL)
- return NULL;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-struct ber_element *
-ber_add_enumerated(struct ber_element *prev, long long val)
-{
- struct ber_element *elm;
- unsigned int i, len = 0;
- unsigned char cur, last = 0;
-
- if ((elm = ber_get_element(BER_TYPE_ENUMERATED)) == NULL)
- return NULL;
-
- elm->be_numeric = val;
-
- for (i = 0; i < sizeof(long long); i++) {
- cur = val & 0xff;
- if (cur != 0 && cur != 0xff)
- len = i;
- if ((cur == 0 && last & 0x80) ||
- (cur == 0xff && (last & 0x80) == 0))
- len = i;
- val >>= 8;
- last = cur;
- }
- elm->be_len = len + 1;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-struct ber_element *
-ber_add_integer(struct ber_element *prev, long long val)
-{
- struct ber_element *elm;
- unsigned int i, len = 0;
- unsigned char cur, last = 0;
-
- if ((elm = ber_get_element(BER_TYPE_INTEGER)) == NULL)
- return NULL;
-
- elm->be_numeric = val;
-
- for (i = 0; i < sizeof(long long); i++) {
- cur = val & 0xff;
- if (cur != 0 && cur != 0xff)
- len = i;
- if ((cur == 0 && last & 0x80) ||
- (cur == 0xff && (last & 0x80) == 0))
- len = i;
- val >>= 8;
- last = cur;
- }
- elm->be_len = len + 1;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-int
-ber_get_integer(struct ber_element *elm, long long *n)
-{
- if (elm->be_encoding != BER_TYPE_INTEGER)
- return -1;
-
- *n = elm->be_numeric;
- return 0;
-}
-
-int
-ber_get_enumerated(struct ber_element *elm, long long *n)
-{
- if (elm->be_encoding != BER_TYPE_ENUMERATED)
- return -1;
-
- *n = elm->be_numeric;
- return 0;
-}
-
-
-struct ber_element *
-ber_add_boolean(struct ber_element *prev, int bool)
-{
- struct ber_element *elm;
-
- if ((elm = ber_get_element(BER_TYPE_BOOLEAN)) == NULL)
- return NULL;
-
- elm->be_numeric = bool ? 0xff : 0;
- elm->be_len = 1;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-int
-ber_get_boolean(struct ber_element *elm, int *b)
-{
- if (elm->be_encoding != BER_TYPE_BOOLEAN)
- return -1;
-
- *b = !(elm->be_numeric == 0);
- return 0;
-}
-
-struct ber_element *
-ber_add_string(struct ber_element *prev, const char *string)
-{
- return ber_add_nstring(prev, string, strlen(string));
-}
-
-struct ber_element *
-ber_add_nstring(struct ber_element *prev, const char *string0, size_t len)
-{
- struct ber_element *elm;
- char *string;
-
- if ((string = calloc(1, len)) == NULL)
- return NULL;
- if ((elm = ber_get_element(BER_TYPE_OCTETSTRING)) == NULL) {
- free(string);
- return NULL;
- }
-
- memmove(string, string0, len);
- elm->be_val = string;
- elm->be_len = len;
- elm->be_free = 1; /* free string on cleanup */
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-int
-ber_get_string(struct ber_element *elm, char **s)
-{
- if (elm->be_encoding != BER_TYPE_OCTETSTRING)
- return -1;
-
- *s = elm->be_val;
- return 0;
-}
-
-int
-ber_get_nstring(struct ber_element *elm, void **p, size_t *len)
-{
- if (elm->be_encoding != BER_TYPE_OCTETSTRING)
- return -1;
-
- *p = elm->be_val;
- *len = elm->be_len;
- return 0;
-}
-
-struct ber_element *
-ber_add_bitstring(struct ber_element *prev, const void *v0, size_t len)
-{
- struct ber_element *elm;
- void *v;
-
- if ((v = calloc(1, len)) == NULL)
- return NULL;
- if ((elm = ber_get_element(BER_TYPE_BITSTRING)) == NULL) {
- free(v);
- return NULL;
- }
-
- memmove(v, v0, len);
- elm->be_val = v;
- elm->be_len = len;
- elm->be_free = 1; /* free string on cleanup */
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-int
-ber_get_bitstring(struct ber_element *elm, void **v, size_t *len)
-{
- if (elm->be_encoding != BER_TYPE_BITSTRING)
- return -1;
-
- *v = elm->be_val;
- *len = elm->be_len;
- return 0;
-}
-
-struct ber_element *
-ber_add_null(struct ber_element *prev)
-{
- struct ber_element *elm;
-
- if ((elm = ber_get_element(BER_TYPE_NULL)) == NULL)
- return NULL;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-int
-ber_get_null(struct ber_element *elm)
-{
- if (elm->be_encoding != BER_TYPE_NULL)
- return -1;
-
- return 0;
-}
-
-struct ber_element *
-ber_add_eoc(struct ber_element *prev)
-{
- struct ber_element *elm;
-
- if ((elm = ber_get_element(BER_TYPE_EOC)) == NULL)
- return NULL;
-
- ber_link_elements(prev, elm);
-
- return elm;
-}
-
-int
-ber_get_eoc(struct ber_element *elm)
-{
- if (elm->be_encoding != BER_TYPE_EOC)
- return -1;
-
- return 0;
-}
-
-size_t
-ber_oid2ber(struct ber_oid *o, uint8_t *buf, size_t len)
-{
- uint32_t v;
- unsigned int i, j = 0, k;
-
- if (o->bo_n < BER_MIN_OID_LEN || o->bo_n > BER_MAX_OID_LEN ||
- o->bo_id[0] > 2 || o->bo_id[1] > 40)
- return (0);
-
- v = (o->bo_id[0] * 40) + o->bo_id[1];
- for (i = 2, j = 0; i <= o->bo_n; v = o->bo_id[i], i++) {
- for (k = 28; k >= 7; k -= 7) {
- if (v >= (unsigned int)(1 << k)) {
- if (len)
- buf[j] = v >> k | BER_TAG_MORE;
- j++;
- }
- }
- if (len)
- buf[j] = v & BER_TAG_TYPE_MASK;
- j++;
- }
-
- return (j);
-}
-
-int
-ber_string2oid(const char *oidstr, struct ber_oid *o)
-{
- char *sp, *p, str[BUFSIZ];
- const char *errstr;
-
- if (strlcpy(str, oidstr, sizeof(str)) >= sizeof(str))
- return (-1);
- memset(o, 0, sizeof(*o));
-
- /* Parse OID strings in the common forms n.n.n, n_n_n_n, or n-n-n */
- for (p = sp = str; p != NULL; sp = p) {
- if ((p = strpbrk(p, "._-")) != NULL)
- *p++ = '\0';
- o->bo_id[o->bo_n++] = strtonum(sp, 0, UINT_MAX, &errstr);
- if (errstr || o->bo_n > BER_MAX_OID_LEN)
- return (-1);
- }
-
- return (0);
-}
-
-struct ber_element *
-ber_add_oid(struct ber_element *prev, struct ber_oid *o)
-{
- struct ber_element *elm;
- uint8_t *buf;
- size_t len;
-
- if ((elm = ber_get_element(BER_TYPE_OBJECT)) == NULL)
- return (NULL);
-
- if ((len = ber_oid2ber(o, NULL, 0)) == 0)
- goto fail;
-
- if ((buf = calloc(1, len)) == NULL)
- goto fail;
-
- elm->be_val = buf;
- elm->be_len = len;
- elm->be_free = 1;
-
- if (ber_oid2ber(o, buf, len) != len)
- goto fail;
-
- ber_link_elements(prev, elm);
-
- return (elm);
-
- fail:
- ber_free_elements(elm);
- return (NULL);
-}
-
-struct ber_element *
-ber_add_noid(struct ber_element *prev, struct ber_oid *o, int n)
-{
- struct ber_oid no;
-
- if (n > BER_MAX_OID_LEN)
- return (NULL);
- no.bo_n = n;
- memmove(&no.bo_id, &o->bo_id, sizeof(no.bo_id));
-
- return (ber_add_oid(prev, &no));
-}
-
-struct ber_element *
-ber_add_oidstring(struct ber_element *prev, const char *oidstr)
-{
- struct ber_oid o;
-
- if (ber_string2oid(oidstr, &o) == -1)
- return (NULL);
-
- return (ber_add_oid(prev, &o));
-}
-
-int
-ber_get_oid(struct ber_element *elm, struct ber_oid *o)
-{
- uint8_t *buf;
- size_t len, i = 0, j = 0;
-
- if (elm->be_encoding != BER_TYPE_OBJECT)
- return (-1);
-
- buf = elm->be_val;
- len = elm->be_len;
-
- if (!buf[i])
- return (-1);
-
- memset(o, 0, sizeof(*o));
- o->bo_id[j++] = buf[i] / 40;
- o->bo_id[j++] = buf[i++] % 40;
- for (; i < len && j < BER_MAX_OID_LEN; i++) {
- o->bo_id[j] = (o->bo_id[j] << 7) + (buf[i] & ~0x80);
- if (buf[i] & 0x80)
- continue;
- j++;
- }
- o->bo_n = j;
-
- return (0);
-}
-
-struct ber_element *
-ber_printf_elements(struct ber_element *ber, char *fmt, ...)
-{
- va_list ap;
- int d, class;
- size_t len;
- unsigned long type;
- long long i;
- char *s;
- void *p;
- struct ber_oid *o;
- struct ber_element *sub = ber, *e;
-
- va_start(ap, fmt);
- while (*fmt) {
- switch (*fmt++) {
- case 'B':
- p = va_arg(ap, void *);
- len = va_arg(ap, size_t);
- if ((ber = ber_add_bitstring(ber, p, len)) == NULL)
- goto fail;
- break;
- case 'b':
- d = va_arg(ap, int);
- if ((ber = ber_add_boolean(ber, d)) == NULL)
- goto fail;
- break;
- case 'd':
- d = va_arg(ap, int);
- if ((ber = ber_add_integer(ber, d)) == NULL)
- goto fail;
- break;
- case 'e':
- e = va_arg(ap, struct ber_element *);
- ber_link_elements(ber, e);
- break;
- case 'E':
- i = va_arg(ap, long long);
- if ((ber = ber_add_enumerated(ber, i)) == NULL)
- goto fail;
- break;
- case 'i':
- i = va_arg(ap, long long);
- if ((ber = ber_add_integer(ber, i)) == NULL)
- goto fail;
- break;
- case 'O':
- o = va_arg(ap, struct ber_oid *);
- if ((ber = ber_add_oid(ber, o)) == NULL)
- goto fail;
- break;
- case 'o':
- s = va_arg(ap, char *);
- if ((ber = ber_add_oidstring(ber, s)) == NULL)
- goto fail;
- break;
- case 's':
- s = va_arg(ap, char *);
- if ((ber = ber_add_string(ber, s)) == NULL)
- goto fail;
- break;
- case 't':
- class = va_arg(ap, int);
- type = va_arg(ap, unsigned long);
- ber_set_header(ber, class, type);
- break;
- case 'x':
- s = va_arg(ap, char *);
- len = va_arg(ap, size_t);
- if ((ber = ber_add_nstring(ber, s, len)) == NULL)
- goto fail;
- break;
- case '0':
- if ((ber = ber_add_null(ber)) == NULL)
- goto fail;
- break;
- case '{':
- if ((ber = sub = ber_add_sequence(ber)) == NULL)
- goto fail;
- break;
- case '(':
- if ((ber = sub = ber_add_set(ber)) == NULL)
- goto fail;
- break;
- case '}':
- case ')':
- ber = sub;
- break;
- case '.':
- if ((e = ber_add_eoc(ber)) == NULL)
- goto fail;
- ber = e;
- break;
- default:
- break;
- }
- }
- va_end(ap);
-
- return (ber);
- fail:
- ber_free_elements(ber);
- return (NULL);
-}
-
-int
-ber_scanf_elements(struct ber_element *ber, char *fmt, ...)
-{
-#define _MAX_SEQ 128
- va_list ap;
- int *d, level = -1;
- unsigned long *t;
- long long *i;
- void **ptr;
- size_t *len, ret = 0, n = strlen(fmt);
- char **s;
- struct ber_oid *o;
- struct ber_element *parent[_MAX_SEQ], **e;
-
- memset(parent, 0, sizeof(struct ber_element *) * _MAX_SEQ);
-
- va_start(ap, fmt);
- while (*fmt) {
- switch (*fmt++) {
- case 'B':
- ptr = va_arg(ap, void **);
- len = va_arg(ap, size_t *);
- if (ber_get_bitstring(ber, ptr, len) == -1)
- goto fail;
- ret++;
- break;
- case 'b':
- d = va_arg(ap, int *);
- if (ber_get_boolean(ber, d) == -1)
- goto fail;
- ret++;
- break;
- case 'e':
- e = va_arg(ap, struct ber_element **);
- *e = ber;
- ret++;
- continue;
- case 'E':
- i = va_arg(ap, long long *);
- if (ber_get_enumerated(ber, i) == -1)
- goto fail;
- ret++;
- break;
- case 'i':
- i = va_arg(ap, long long *);
- if (ber_get_integer(ber, i) == -1)
- goto fail;
- ret++;
- break;
- case 'o':
- o = va_arg(ap, struct ber_oid *);
- if (ber_get_oid(ber, o) == -1)
- goto fail;
- ret++;
- break;
- case 'S':
- ret++;
- break;
- case 's':
- s = va_arg(ap, char **);
- if (ber_get_string(ber, s) == -1)
- goto fail;
- ret++;
- break;
- case 't':
- d = va_arg(ap, int *);
- t = va_arg(ap, unsigned long *);
- *d = ber->be_class;
- *t = ber->be_type;
- ret++;
- continue;
- case 'x':
- ptr = va_arg(ap, void **);
- len = va_arg(ap, size_t *);
- if (ber_get_nstring(ber, ptr, len) == -1)
- goto fail;
- ret++;
- break;
- case '0':
- if (ber->be_encoding != BER_TYPE_NULL)
- goto fail;
- ret++;
- break;
- case '.':
- if (ber->be_encoding != BER_TYPE_EOC)
- goto fail;
- ret++;
- break;
- case '{':
- case '(':
- if (ber->be_encoding != BER_TYPE_SEQUENCE &&
- ber->be_encoding != BER_TYPE_SET)
- goto fail;
- if (ber->be_sub == NULL || level >= _MAX_SEQ-1)
- goto fail;
- parent[++level] = ber;
- ber = ber->be_sub;
- ret++;
- continue;
- case '}':
- case ')':
- if (parent[level] == NULL)
- goto fail;
- ber = parent[level--];
- ret++;
- continue;
- default:
- goto fail;
- }
-
- if (ber->be_next == NULL)
- continue;
- ber = ber->be_next;
- }
- va_end(ap);
- return (ret == n ? 0 : -1);
-
- fail:
- va_end(ap);
- return (-1);
-
-}
-
-/*
- * write ber elements to the socket
- *
- * params:
- * ber holds the socket
- * root fully populated element tree
- *
- * returns:
- * >=0 number of bytes written
- * -1 on failure and sets errno
- */
-int
-ber_write_elements(struct ber *ber, struct ber_element *root)
-{
- size_t len;
-
- /* calculate length because only the definite form is required */
- len = ber_calc_len(root);
- DPRINTF("write ber element of %zd bytes length\n", len);
-
- if (ber->br_wbuf != NULL && ber->br_wbuf + len > ber->br_wend) {
- free(ber->br_wbuf);
- ber->br_wbuf = NULL;
- }
- if (ber->br_wbuf == NULL) {
- if ((ber->br_wbuf = malloc(len)) == NULL)
- return -1;
- ber->br_wend = ber->br_wbuf + len;
- }
-
- /* reset write pointer */
- ber->br_wptr = ber->br_wbuf;
-
- if (ber_dump_element(ber, root) == -1)
- return -1;
-
- /* XXX this should be moved to a different function */
- if (ber->fd != -1)
- return write(ber->fd, ber->br_wbuf, len);
-
- return (len);
-}
-
-/*
- * read ber elements from the socket
- *
- * params:
- * ber holds the socket and lot more
- * root if NULL, build up an element tree from what we receive on
- * the wire. If not null, use the specified encoding for the
- * elements received.
- *
- * returns:
- * !=NULL, elements read and store in the ber_element tree
- * NULL, type mismatch or read error
- */
-struct ber_element *
-ber_read_elements(struct ber *ber, struct ber_element *elm)
-{
- struct ber_element *root = elm;
-
- if (root == NULL) {
- if ((root = ber_get_element(0)) == NULL)
- return NULL;
- }
-
- DPRINTF("read ber elements, root %p\n", root);
-
- if (ber_read_element(ber, root) == -1) {
- /* Cleanup if root was allocated by us */
- if (elm == NULL)
- ber_free_elements(root);
- return NULL;
- }
-
- return root;
-}
-
-void
-ber_free_elements(struct ber_element *root)
-{
- if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE ||
- root->be_encoding == BER_TYPE_SET))
- ber_free_elements(root->be_sub);
- if (root->be_next)
- ber_free_elements(root->be_next);
- if (root->be_free && (root->be_encoding == BER_TYPE_OCTETSTRING ||
- root->be_encoding == BER_TYPE_BITSTRING ||
- root->be_encoding == BER_TYPE_OBJECT))
- free(root->be_val);
- free(root);
-}
-
-size_t
-ber_calc_len(struct ber_element *root)
-{
- unsigned long t;
- size_t s;
- size_t size = 2; /* minimum 1 byte head and 1 byte size */
-
- /* calculate the real length of a sequence or set */
- if (root->be_sub && (root->be_encoding == BER_TYPE_SEQUENCE ||
- root->be_encoding == BER_TYPE_SET))
- root->be_len = ber_calc_len(root->be_sub);
-
- /* fix header length for extended types */
- if (root->be_type > BER_TYPE_SINGLE_MAX)
- for (t = root->be_type; t > 0; t >>= 7)
- size++;
- if (root->be_len >= BER_TAG_MORE)
- for (s = root->be_len; s > 0; s >>= 8)
- size++;
-
- /* calculate the length of the following elements */
- if (root->be_next)
- size += ber_calc_len(root->be_next);
-
- /* This is an empty element, do not use a minimal size */
- if (root->be_type == BER_TYPE_EOC && root->be_len == 0)
- return (0);
-
- return (root->be_len + size);
-}
-
-/*
- * internal functions
- */
-
-static int
-ber_dump_element(struct ber *ber, struct ber_element *root)
-{
- unsigned long long l;
- int i;
- uint8_t u;
-
- ber_dump_header(ber, root);
-
- switch (root->be_encoding) {
- case BER_TYPE_BOOLEAN:
- case BER_TYPE_INTEGER:
- case BER_TYPE_ENUMERATED:
- l = (unsigned long long)root->be_numeric;
- for (i = root->be_len; i > 0; i--) {
- u = (l >> ((i - 1) * 8)) & 0xff;
- ber_putc(ber, u);
- }
- break;
- case BER_TYPE_BITSTRING:
- return -1;
- case BER_TYPE_OCTETSTRING:
- case BER_TYPE_OBJECT:
- ber_write(ber, root->be_val, root->be_len);
- break;
- case BER_TYPE_NULL: /* no payload */
- case BER_TYPE_EOC:
- break;
- case BER_TYPE_SEQUENCE:
- case BER_TYPE_SET:
- if (root->be_sub && ber_dump_element(ber, root->be_sub) == -1)
- return -1;
- break;
- }
-
- if (root->be_next == NULL)
- return 0;
- return ber_dump_element(ber, root->be_next);
-}
-
-static void
-ber_dump_header(struct ber *ber, struct ber_element *root)
-{
- unsigned char id = 0, t, buf[8];
- unsigned long type;
- size_t size;
-
- /* class universal, type encoding depending on type value */
- /* length encoding */
- if (root->be_type <= BER_TYPE_SINGLE_MAX) {
- id = root->be_type | (root->be_class << BER_CLASS_SHIFT);
- if (root->be_encoding == BER_TYPE_SEQUENCE ||
- root->be_encoding == BER_TYPE_SET)
- id |= BER_TYPE_CONSTRUCTED;
-
- ber_putc(ber, id);
- } else {
- id = BER_TAG_MASK | (root->be_class << BER_CLASS_SHIFT);
- if (root->be_encoding == BER_TYPE_SEQUENCE ||
- root->be_encoding == BER_TYPE_SET)
- id |= BER_TYPE_CONSTRUCTED;
-
- ber_putc(ber, id);
-
- for (t = 0, type = root->be_type; type > 0; type >>= 7)
- buf[t++] = type & ~BER_TAG_MORE;
-
- while (t-- > 0) {
- if (t > 0)
- buf[t] |= BER_TAG_MORE;
- ber_putc(ber, buf[t]);
- }
- }
-
- if (root->be_len < BER_TAG_MORE) {
- /* short form */
- ber_putc(ber, root->be_len);
- } else {
- for (t = 0, size = root->be_len; size > 0; size >>= 8)
- buf[t++] = size & 0xff;
-
- ber_putc(ber, t | BER_TAG_MORE);
-
- while (t > 0)
- ber_putc(ber, buf[--t]);
- }
-}
-
-static void
-ber_putc(struct ber *ber, unsigned char c)
-{
- if (ber->br_wptr + 1 <= ber->br_wend)
- *ber->br_wptr = c;
- ber->br_wptr++;
-}
-
-static void
-ber_write(struct ber *ber, void *buf, size_t len)
-{
- if (ber->br_wptr + len <= ber->br_wend)
- memmove(ber->br_wptr, buf, len);
-
- ber->br_wptr += len;
-}
-
-/*
- * extract a BER encoded tag. There are two types, a short and long form.
- */
-static ssize_t
-get_id(struct ber *b, unsigned long *tag, int *class, int *cstruct)
-{
- unsigned char u;
- size_t i = 0;
- unsigned long t = 0;
-
- if (ber_getc(b, &u) == -1)
- return -1;
-
- *class = (u >> BER_CLASS_SHIFT) & BER_CLASS_MASK;
- *cstruct = (u & BER_TYPE_CONSTRUCTED) == BER_TYPE_CONSTRUCTED;
-
- if ((u & BER_TAG_MASK) != BER_TAG_MASK) {
- *tag = u & BER_TAG_MASK;
- return 1;
- }
-
- do {
- if (ber_getc(b, &u) == -1)
- return -1;
- t = (t << 7) | (u & ~BER_TAG_MORE);
- i++;
- } while (u & BER_TAG_MORE);
-
- if (i > sizeof(unsigned long)) {
- errno = ERANGE;
- return -1;
- }
-
- *tag = t;
- return i + 1;
-}
-
-/*
- * extract length of a ber object -- if length is unknown an error is returned.
- */
-static ssize_t
-get_len(struct ber *b, ssize_t *len)
-{
- unsigned char u, n;
- ssize_t s, r;
-
- if (ber_getc(b, &u) == -1)
- return -1;
- if ((u & BER_TAG_MORE) == 0) {
- /* short form */
- *len = u;
- return 1;
- }
-
- n = u & ~BER_TAG_MORE;
- if (sizeof(ssize_t) < n) {
- errno = ERANGE;
- return -1;
- }
- r = n + 1;
-
- for (s = 0; n > 0; n--) {
- if (ber_getc(b, &u) == -1)
- return -1;
- s = (s << 8) | u;
- }
-
- if (s < 0) {
- /* overflow */
- errno = ERANGE;
- return -1;
- }
-
- if (s == 0) {
- /* invalid encoding */
- errno = EINVAL;
- return -1;
- }
-
- *len = s;
- return r;
-}
-
-static ssize_t
-ber_read_element(struct ber *ber, struct ber_element *elm)
-{
- long long val = 0;
- struct ber_element *next;
- unsigned long type;
- int i, class, cstruct;
- ssize_t len, r, totlen = 0;
- unsigned char c;
-
- if ((r = get_id(ber, &type, &class, &cstruct)) == -1)
- return -1;
- DPRINTF("ber read got class %d type %lu, %s\n",
- class, type, cstruct ? "constructive" : "primitive");
- totlen += r;
- if ((r = get_len(ber, &len)) == -1)
- return -1;
- DPRINTF("ber read element size %zd\n", len);
- totlen += r + len;
-
- elm->be_type = type;
- elm->be_len = len;
- elm->be_class = class;
-
- if (elm->be_encoding == 0) {
- /* try to figure out the encoding via class, type and cstruct */
- if (cstruct)
- elm->be_encoding = BER_TYPE_SEQUENCE;
- else if (class == BER_CLASS_UNIVERSAL)
- elm->be_encoding = type;
- else if (ber->br_application != NULL) {
- /*
- * Ask the application to map the encoding to a
- * universal type. For example, a SMI IpAddress
- * type is defined as 4 byte OCTET STRING.
- */
- elm->be_encoding = (*ber->br_application)(elm);
- } else
- /* last resort option */
- elm->be_encoding = BER_TYPE_NULL;
- }
-
- switch (elm->be_encoding) {
- case BER_TYPE_EOC: /* End-Of-Content */
- break;
- case BER_TYPE_BOOLEAN:
- case BER_TYPE_INTEGER:
- case BER_TYPE_ENUMERATED:
- if (len > (ssize_t)sizeof(long long))
- return -1;
- for (i = 0; i < len; i++) {
- if (ber_getc(ber, &c) != 1)
- return -1;
- val <<= 8;
- val |= c;
- }
-
- /* sign extend if MSB is set */
- if (val >> ((i - 1) * 8) & 0x80)
- val |= ULLONG_MAX << (i * 8);
- elm->be_numeric = val;
- break;
- case BER_TYPE_BITSTRING:
- elm->be_val = malloc(len);
- if (elm->be_val == NULL)
- return -1;
- elm->be_free = 1;
- elm->be_len = len;
- ber_read(ber, elm->be_val, len);
- break;
- case BER_TYPE_OCTETSTRING:
- case BER_TYPE_OBJECT:
- elm->be_val = malloc(len + 1);
- if (elm->be_val == NULL)
- return -1;
- elm->be_free = 1;
- elm->be_len = len;
- ber_read(ber, elm->be_val, len);
- ((unsigned char *)elm->be_val)[len] = '\0';
- break;
- case BER_TYPE_NULL: /* no payload */
- if (len != 0)
- return -1;
- break;
- case BER_TYPE_SEQUENCE:
- case BER_TYPE_SET:
- if (elm->be_sub == NULL) {
- if ((elm->be_sub = ber_get_element(0)) == NULL)
- return -1;
- }
- next = elm->be_sub;
- while (len > 0) {
- r = ber_read_element(ber, next);
- if (r == -1)
- return -1;
- len -= r;
- if (len > 0 && next->be_next == NULL) {
- if ((next->be_next = ber_get_element(0)) ==
- NULL)
- return -1;
- }
- next = next->be_next;
- }
- break;
- }
- return totlen;
-}
-
-static ssize_t
-ber_readbuf(struct ber *b, void *buf, size_t nbytes)
-{
- size_t sz;
- size_t len;
-
- if (b->br_rbuf == NULL)
- return -1;
-
- sz = b->br_rend - b->br_rptr;
- len = MINIMUM(nbytes, sz);
- if (len == 0) {
- errno = ECANCELED;
- return (-1); /* end of buffer and parser wants more data */
- }
-
- memmove(buf, b->br_rptr, len);
- b->br_rptr += len;
-
- return (len);
-}
-
-void
-ber_set_readbuf(struct ber *b, void *buf, size_t len)
-{
- b->br_rbuf = b->br_rptr = buf;
- b->br_rend = (uint8_t *)buf + len;
-}
-
-ssize_t
-ber_get_writebuf(struct ber *b, void **buf)
-{
- if (b->br_wbuf == NULL)
- return -1;
- *buf = b->br_wbuf;
- return (b->br_wend - b->br_wbuf);
-}
-
-void
-ber_set_application(struct ber *b, unsigned long (*cb)(struct ber_element *))
-{
- b->br_application = cb;
-}
-
-void
-ber_free(struct ber *b)
-{
- if (b->br_wbuf != NULL)
- free (b->br_wbuf);
-}
-
-static ssize_t
-ber_getc(struct ber *b, unsigned char *c)
-{
- ssize_t r;
- /*
- * XXX calling read here is wrong in many ways. The most obvious one
- * being that we will block till data arrives.
- * But for now it is _good enough_ *gulp*
- */
- if (b->fd == -1)
- r = ber_readbuf(b, c, 1);
- else
- r = read(b->fd, c, 1);
- return r;
-}
-
-static ssize_t
-ber_read(struct ber *ber, void *buf, size_t len)
-{
- unsigned char *b = buf;
- ssize_t r, remain = len;
-
- /*
- * XXX calling read here is wrong in many ways. The most obvious one
- * being that we will block till data arrives.
- * But for now it is _good enough_ *gulp*
- */
-
- while (remain > 0) {
- if (ber->fd == -1)
- r = ber_readbuf(ber, b, remain);
- else
- r = read(ber->fd, b, remain);
- if (r == -1) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
- return -1;
- }
- if (r == 0)
- return (b - (unsigned char *)buf);
- b += r;
- remain -= r;
- }
- return (b - (unsigned char *)buf);
-}
diff --git a/usr.sbin/smtpd/ber.h b/usr.sbin/smtpd/ber.h
deleted file mode 100644
index 525e5451dd2..00000000000
--- a/usr.sbin/smtpd/ber.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* $OpenBSD: ber.h,v 1.4 2015/11/05 12:35:58 jung Exp $ */
-
-/*
- * Copyright (c) 2007 Reyk Floeter <reyk@vantronix.net>
- * Copyright (c) 2006, 2007 Claudio Jeker <claudio@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.
- */
-
-struct ber_element {
- struct ber_element *be_next;
- unsigned long be_type;
- unsigned long be_encoding;
- size_t be_len;
- int be_free;
- uint8_t be_class;
- union {
- struct ber_element *bv_sub;
- void *bv_val;
- long long bv_numeric;
- } be_union;
-#define be_sub be_union.bv_sub
-#define be_val be_union.bv_val
-#define be_numeric be_union.bv_numeric
-};
-
-struct ber {
- int fd;
- unsigned char *br_wbuf;
- unsigned char *br_wptr;
- unsigned char *br_wend;
- unsigned char *br_rbuf;
- unsigned char *br_rptr;
- unsigned char *br_rend;
-
- unsigned long (*br_application)(struct ber_element *);
-};
-
-/* well-known ber_element types */
-#define BER_TYPE_DEFAULT ((unsigned long)-1)
-#define BER_TYPE_EOC 0
-#define BER_TYPE_BOOLEAN 1
-#define BER_TYPE_INTEGER 2
-#define BER_TYPE_BITSTRING 3
-#define BER_TYPE_OCTETSTRING 4
-#define BER_TYPE_NULL 5
-#define BER_TYPE_OBJECT 6
-#define BER_TYPE_ENUMERATED 10
-#define BER_TYPE_SEQUENCE 16
-#define BER_TYPE_SET 17
-
-/* ber classes */
-#define BER_CLASS_UNIVERSAL 0x0
-#define BER_CLASS_UNIV BER_CLASS_UNIVERSAL
-#define BER_CLASS_APPLICATION 0x1
-#define BER_CLASS_APP BER_CLASS_APPLICATION
-#define BER_CLASS_CONTEXT 0x2
-#define BER_CLASS_PRIVATE 0x3
-#define BER_CLASS_MASK 0x3
-
-/* common definitions */
-#define BER_MIN_OID_LEN 2 /* OBJECT */
-#define BER_MAX_OID_LEN 32 /* OBJECT */
-
-struct ber_oid {
- uint32_t bo_id[BER_MAX_OID_LEN + 1];
- size_t bo_n;
-};
-
-__BEGIN_DECLS
-struct ber_element *ber_get_element(unsigned long);
-void ber_set_header(struct ber_element *, int,
- unsigned long);
-void ber_link_elements(struct ber_element *,
- struct ber_element *);
-struct ber_element *ber_unlink_elements(struct ber_element *);
-void ber_replace_elements(struct ber_element *,
- struct ber_element *);
-struct ber_element *ber_add_sequence(struct ber_element *);
-struct ber_element *ber_add_set(struct ber_element *);
-struct ber_element *ber_add_integer(struct ber_element *, long long);
-int ber_get_integer(struct ber_element *, long long *);
-struct ber_element *ber_add_enumerated(struct ber_element *, long long);
-int ber_get_enumerated(struct ber_element *, long long *);
-struct ber_element *ber_add_boolean(struct ber_element *, int);
-int ber_get_boolean(struct ber_element *, int *);
-struct ber_element *ber_add_string(struct ber_element *, const char *);
-struct ber_element *ber_add_nstring(struct ber_element *, const char *,
- size_t);
-int ber_get_string(struct ber_element *, char **);
-int ber_get_nstring(struct ber_element *, void **,
- size_t *);
-struct ber_element *ber_add_bitstring(struct ber_element *, const void *,
- size_t);
-int ber_get_bitstring(struct ber_element *, void **,
- size_t *);
-struct ber_element *ber_add_null(struct ber_element *);
-int ber_get_null(struct ber_element *);
-struct ber_element *ber_add_eoc(struct ber_element *);
-int ber_get_eoc(struct ber_element *);
-struct ber_element *ber_add_oid(struct ber_element *, struct ber_oid *);
-struct ber_element *ber_add_noid(struct ber_element *, struct ber_oid *, int);
-struct ber_element *ber_add_oidstring(struct ber_element *, const char *);
-int ber_get_oid(struct ber_element *, struct ber_oid *);
-size_t ber_oid2ber(struct ber_oid *, uint8_t *, size_t);
-int ber_string2oid(const char *, struct ber_oid *);
-struct ber_element *ber_printf_elements(struct ber_element *, char *, ...);
-int ber_scanf_elements(struct ber_element *, char *, ...);
-ssize_t ber_get_writebuf(struct ber *, void **);
-int ber_write_elements(struct ber *, struct ber_element *);
-void ber_set_readbuf(struct ber *, void *, size_t);
-struct ber_element *ber_read_elements(struct ber *, struct ber_element *);
-void ber_free_elements(struct ber_element *);
-size_t ber_calc_len(struct ber_element *);
-void ber_set_application(struct ber *,
- unsigned long (*)(struct ber_element *));
-void ber_free(struct ber *);
-__END_DECLS
diff --git a/usr.sbin/smtpd/table-ldap/Makefile b/usr.sbin/smtpd/table-ldap/Makefile
deleted file mode 100644
index 2b9d700dff6..00000000000
--- a/usr.sbin/smtpd/table-ldap/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# $OpenBSD: Makefile,v 1.5 2015/10/06 00:30:32 deraadt Exp $
-
-.PATH: ${.CURDIR}/..
-
-PROG= table-ldap
-
-SRCS= table_ldap.c
-SRCS+= table_api.c
-SRCS+= aldap.c
-SRCS+= ber.c
-SRCS+= dict.c
-SRCS+= log.c
-
-NOMAN= noman
-
-BINDIR= /usr/libexec/smtpd
-
-DPADD= ${LIBUTIL}
-LDADD= -lutil
-
-CFLAGS+= -fstack-protector-all
-CFLAGS+= -I${.CURDIR}/..
-CFLAGS+= -Wall -Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+= -Wmissing-declarations
-CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+= -Wsign-compare
-CFLAGS+= -DNO_IO
-#CFLAGS+= -Werror # during development phase (breaks some archs)
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/smtpd/table-passwd/Makefile b/usr.sbin/smtpd/table-passwd/Makefile
deleted file mode 100644
index b542368b71d..00000000000
--- a/usr.sbin/smtpd/table-passwd/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# $OpenBSD: Makefile,v 1.5 2015/10/06 00:30:32 deraadt Exp $
-
-.PATH: ${.CURDIR}/..
-
-PROG= table-passwd
-
-SRCS= table_passwd.c
-SRCS+= table_api.c
-SRCS+= dict.c
-SRCS+= log.c
-
-MAN= table_passwd.5
-
-BINDIR= /usr/libexec/smtpd
-
-DPADD= ${LIBUTIL}
-LDADD= -lutil
-
-CFLAGS+= -fstack-protector-all
-CFLAGS+= -I${.CURDIR}/..
-CFLAGS+= -Wall -Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+= -Wmissing-declarations
-CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+= -Wsign-compare
-CFLAGS+= -DNO_IO
-#CFLAGS+= -Werror # during development phase (breaks some archs)
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/smtpd/table-sqlite/Makefile b/usr.sbin/smtpd/table-sqlite/Makefile
deleted file mode 100644
index eb69c00f1b3..00000000000
--- a/usr.sbin/smtpd/table-sqlite/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# $OpenBSD: Makefile,v 1.4 2015/10/06 00:30:32 deraadt Exp $
-
-.PATH: ${.CURDIR}/..
-
-PROG= table-sqlite
-
-SRCS= table_sqlite.c
-SRCS+= table_api.c
-SRCS+= dict.c
-SRCS+= log.c
-
-NOMAN= noman
-
-BINDIR= /usr/libexec/smtpd
-
-DPADD= ${LIBUTIL} ${LIBSQLITE3}
-LDADD= -lutil -lsqlite3
-
-CFLAGS+= -fstack-protector-all
-CFLAGS+= -I${.CURDIR}/..
-CFLAGS+= -Wall -Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+= -Wmissing-declarations
-CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+= -Wsign-compare
-CFLAGS+= -DNO_IO
-#CFLAGS+= -Werror # during development phase (breaks some archs)
-
-.include <bsd.prog.mk>
diff --git a/usr.sbin/smtpd/table_ldap.c b/usr.sbin/smtpd/table_ldap.c
deleted file mode 100644
index cc650f33b23..00000000000
--- a/usr.sbin/smtpd/table_ldap.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/* $OpenBSD: table_ldap.c,v 1.15 2015/10/11 12:50:00 sunil Exp $ */
-
-/*
- * Copyright (c) 2013 Eric Faurot <eric@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/socket.h>
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "smtpd-defines.h"
-#include "smtpd-api.h"
-#include "log.h"
-#include "aldap.h"
-
-#define MAX_LDAP_IDENTIFIER 32
-#define MAX_LDAP_URL 256
-#define MAX_LDAP_USERNAME 256
-#define MAX_LDAP_PASSWORD 256
-#define MAX_LDAP_BASELEN 128
-#define MAX_LDAP_FILTERLEN 1024
-#define MAX_LDAP_FIELDLEN 128
-
-
-enum {
- LDAP_ALIAS = 0,
- LDAP_DOMAIN,
- LDAP_CREDENTIALS,
- LDAP_NETADDR,
- LDAP_USERINFO,
- LDAP_SOURCE,
- LDAP_MAILADDR,
- LDAP_ADDRNAME,
-
- LDAP_MAX
-};
-
-#define MAX_ATTRS 6
-
-struct query {
- char *filter;
- char *attrs[MAX_ATTRS];
- int attrn;
-};
-
-static int table_ldap_update(void);
-static int table_ldap_check(int, struct dict *, const char *);
-static int table_ldap_lookup(int, struct dict *, const char *, char *, size_t);
-static int table_ldap_fetch(int, struct dict *, char *, size_t);
-
-static int ldap_config(void);
-static int ldap_open(void);
-static int ldap_query(const char *, char **, char ***, size_t);
-static int ldap_parse_attributes(struct query *, const char *, const char *, size_t);
-static int ldap_run_query(int type, const char *, char *, size_t);
-
-static char *config;
-
-static char *url;
-static char *username;
-static char *password;
-static char *basedn;
-
-static struct aldap *aldap;
-static struct query queries[LDAP_MAX];
-
-int
-main(int argc, char **argv)
-{
- int ch;
-
- log_init(1);
- log_verbose(~0);
-
- while ((ch = getopt(argc, argv, "")) != -1) {
- switch (ch) {
- default:
- log_warnx("warn: table-ldap: bad option");
- return (1);
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- log_warnx("warn: table-ldap: bogus argument(s)");
- return (1);
- }
-
- config = argv[0];
-
- if (!ldap_config()) {
- log_warnx("warn: table-ldap: could not parse config");
- return (1);
- }
-
- log_debug("debug: table-ldap: done reading config");
-
- if (!ldap_open()) {
- log_warnx("warn: table-ldap: failed to connect");
- return (1);
- }
-
- log_debug("debug: table-ldap: connected");
-
- table_api_on_update(table_ldap_update);
- table_api_on_check(table_ldap_check);
- table_api_on_lookup(table_ldap_lookup);
- table_api_on_fetch(table_ldap_fetch);
- table_api_dispatch();
-
- return (0);
-}
-
-static int
-table_ldap_update(void)
-{
- return (1);
-}
-
-static int
-table_ldap_check(int service, struct dict *params, const char *key)
-{
- switch(service) {
- case K_ALIAS:
- case K_DOMAIN:
- case K_CREDENTIALS:
- case K_USERINFO:
- case K_MAILADDR:
- return ldap_run_query(service, key, NULL, 0);
- default:
- return (-1);
- }
-}
-
-static int
-table_ldap_lookup(int service, struct dict *params, const char *key, char *dst, size_t sz)
-{
- switch(service) {
- case K_ALIAS:
- case K_DOMAIN:
- case K_CREDENTIALS:
- case K_USERINFO:
- case K_MAILADDR:
- return ldap_run_query(service, key, dst, sz);
- default:
- return (-1);
- }
-}
-
-static int
-table_ldap_fetch(int service, struct dict *params, char *dst, size_t sz)
-{
- return (-1);
-}
-
-static struct aldap *
-ldap_connect(const char *addr)
-{
- struct aldap_url lu;
- struct addrinfo hints, *res0, *res;
- char *buf;
- int error, fd = -1;
-
- if ((buf = strdup(addr)) == NULL)
- return (NULL);
-
- /* aldap_parse_url frees buf on success */
- if (aldap_parse_url(buf, &lu) != 1) {
- log_warnx("warn: table-ldap: ldap_parse_url fail");
- free(buf);
- return (NULL);
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM; /* DUMMY */
- error = getaddrinfo(lu.host, NULL, &hints, &res0);
- if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
- return (NULL);
- if (error) {
- log_warnx("warn: table-ldap: could not parse \"%s\": %s",
- lu.host, gai_strerror(error));
- return (NULL);
- }
-
- for (res = res0; res; res = res->ai_next) {
- if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
- continue;
-
- fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (fd == -1)
- continue;
-
- if (res->ai_family == AF_INET) {
- struct sockaddr_in sin4 = *(struct sockaddr_in *)res->ai_addr;
- sin4.sin_port = htons(lu.port);
- if (connect(fd, (struct sockaddr *)&sin4, res->ai_addrlen) == 0)
- return aldap_init(fd);
- }
- else if (res->ai_family == AF_INET6) {
- struct sockaddr_in6 sin6 = *(struct sockaddr_in6 *)res->ai_addr;
- sin6.sin6_port = htons(lu.port);
- if (connect(fd, (struct sockaddr *)&sin6, res->ai_addrlen) == 0)
- return aldap_init(fd);
- }
-
- close(fd);
- fd = -1;
- }
-
- return (NULL);
-}
-
-static int
-read_value(char **store, const char *key, const char *value)
-{
- log_debug("debug: table-ldap: reading key \"%s\" -> \"%s\"",
- key, value);
-
- if (*store) {
- log_warnx("warn: table-ldap: duplicate key %s", key);
- return (0);
- }
-
- if ((*store = strdup(value)) == NULL) {
- log_warn("warn: table-ldap: strdup");
- return (0);
- }
-
- return (1);
-}
-
-static int
-ldap_parse_attributes(struct query *query, const char *key, const char *line,
- size_t expect)
-{
- char buffer[1024];
- char *p;
- size_t m, n;
-
- log_debug("debug: table-ldap: parsing attribute \"%s\" (%zu) -> \"%s\"",
- key, expect, line);
-
- if (strlcpy(buffer, line, sizeof buffer) >= sizeof buffer)
- return (0);
-
- m = 1;
- for (p = buffer; *p; ++p) {
- if (*p == ',') {
- *p = 0;
- m++;
- }
- }
- if (expect != m)
- return (0);
-
- p = buffer;
- for (n = 0; n < expect; ++n)
- query->attrs[n] = NULL;
- for (n = 0; n < m; ++n) {
- query->attrs[n] = strdup(p);
- if (query->attrs[n] == NULL) {
- log_warnx("warn: table-ldap: strdup");
- return (0); /* XXX cleanup */
- }
- p += strlen(p) + 1;
- query->attrn++;
- }
- return (1);
-}
-
-static int
-ldap_config(void)
-{
- size_t sz = 0;
- ssize_t flen;
- FILE *fp;
- char *key, *value, *buf = NULL;
-
- fp = fopen(config, "r");
- if (fp == NULL)
- return (0);
-
- while ((flen = getline(&buf, &sz, fp)) != -1) {
- if (buf[flen - 1] == '\n')
- buf[flen - 1] = '\0';
-
- key = buf;
- while (isspace((unsigned char)*key))
- ++key;
- if (*key == '\0' || *key == '#')
- continue;
- value = key;
- strsep(&value, " \t:");
- if (value) {
- while (*value) {
- if (!isspace((unsigned char)*value) &&
- !(*value == ':' && isspace((unsigned char)*(value + 1))))
- break;
- ++value;
- }
- if (*value == '\0')
- value = NULL;
- }
-
- if (value == NULL) {
- log_warnx("warn: table-ldap: missing value for key %s", key);
- continue;
- }
-
- if (!strcmp(key, "url"))
- read_value(&url, key, value);
- else if (!strcmp(key, "username"))
- read_value(&username, key, value);
- else if (!strcmp(key, "password"))
- read_value(&password, key, value);
- else if (!strcmp(key, "basedn"))
- read_value(&basedn, key, value);
-
- else if (!strcmp(key, "alias_filter"))
- read_value(&queries[LDAP_ALIAS].filter, key, value);
- else if (!strcmp(key, "alias_attributes")) {
- ldap_parse_attributes(&queries[LDAP_ALIAS],
- key, value, 1);
- }
-
- else if (!strcmp(key, "credentials_filter"))
- read_value(&queries[LDAP_CREDENTIALS].filter, key, value);
- else if (!strcmp(key, "credentials_attributes")) {
- ldap_parse_attributes(&queries[LDAP_CREDENTIALS],
- key, value, 2);
- }
-
- else if (!strcmp(key, "domain_filter"))
- read_value(&queries[LDAP_DOMAIN].filter, key, value);
- else if (!strcmp(key, "domain_attributes")) {
- ldap_parse_attributes(&queries[LDAP_DOMAIN],
- key, value, 1);
- }
-
- else if (!strcmp(key, "userinfo_filter"))
- read_value(&queries[LDAP_USERINFO].filter, key, value);
- else if (!strcmp(key, "userinfo_attributes")) {
- ldap_parse_attributes(&queries[LDAP_USERINFO],
- key, value, 3);
- }
-
- else if (!strcmp(key, "mailaddr_filter"))
- read_value(&queries[LDAP_MAILADDR].filter, key, value);
- else if (!strcmp(key, "mailaddr_attributes")) {
- ldap_parse_attributes(&queries[LDAP_MAILADDR],
- key, value, 1);
- }
- else
- log_warnx("warn: table-ldap: bogus entry \"%s\"", key);
- }
-
- free(buf);
- fclose(fp);
- return (1);
-}
-
-static int
-ldap_open(void)
-{
- struct aldap_message *amsg = NULL;
-
- aldap = ldap_connect(url);
- if (aldap == NULL) {
- log_warnx("warn: table-ldap: ldap_connect error");
- goto err;
- }
-
- if (aldap_bind(aldap, username, password) == -1) {
- log_warnx("warn: table-ldap: aldap_bind error");
- goto err;
- }
-
- if ((amsg = aldap_parse(aldap)) == NULL) {
- log_warnx("warn: table-ldap: aldap_parse");
- goto err;
- }
-
- switch (aldap_get_resultcode(amsg)) {
- case LDAP_SUCCESS:
- log_debug("debug: table-ldap: ldap server accepted credentials");
- break;
- case LDAP_INVALID_CREDENTIALS:
- log_warnx("warn: table-ldap: ldap server refused credentials");
- goto err;
- default:
- log_warnx("warn: table-ldap: failed to bind, result #%d",
- aldap_get_resultcode(amsg));
- goto err;
- }
-
- if (amsg)
- aldap_freemsg(amsg);
- return (1);
-
-err:
- if (aldap)
- aldap_close(aldap);
- if (amsg)
- aldap_freemsg(amsg);
- return (0);
-}
-
-static int
-ldap_query(const char *filter, char **attributes, char ***outp, size_t n)
-{
- struct aldap_message *m = NULL;
- struct aldap_page_control *pg = NULL;
- int ret, found;
- size_t i;
- char basedn__[MAX_LDAP_BASELEN];
- char filter__[MAX_LDAP_FILTERLEN];
-
- if (strlcpy(basedn__, basedn, sizeof basedn__) >= sizeof basedn__)
- return -1;
- if (strlcpy(filter__, filter, sizeof filter__) >= sizeof filter__)
- return -1;
- found = 0;
- do {
- if ((ret = aldap_search(aldap, basedn__, LDAP_SCOPE_SUBTREE,
- filter__, NULL, 0, 0, 0, pg)) == -1) {
- log_debug("ret=%d", ret);
- return -1;
- }
- if (pg != NULL) {
- aldap_freepage(pg);
- pg = NULL;
- }
-
- while ((m = aldap_parse(aldap)) != NULL) {
- if (aldap->msgid != m->msgid)
- goto error;
- if (m->message_type == LDAP_RES_SEARCH_RESULT) {
- if (m->page != NULL && m->page->cookie_len)
- pg = m->page;
- aldap_freemsg(m);
- m = NULL;
- break;
- }
- if (m->message_type != LDAP_RES_SEARCH_ENTRY)
- goto error;
-
- found = 1;
- for (i = 0; i < n; ++i)
- if (aldap_match_attr(m, attributes[i], &outp[i]) != 1)
- goto error;
- aldap_freemsg(m);
- m = NULL;
- }
- } while (pg != NULL);
-
- ret = found ? 1 : 0;
- goto end;
-
-error:
- ret = -1;
-
-end:
- if (m)
- aldap_freemsg(m);
- log_debug("debug: table_ldap: ldap_query: filter=%s, ret=%d", filter, ret);
- return ret;
-}
-
-static int
-ldap_run_query(int type, const char *key, char *dst, size_t sz)
-{
- struct query *q;
- char **res[4], filter[MAX_LDAP_FILTERLEN];
- int ret, i;
-
- switch (type) {
- case K_ALIAS: q = &queries[LDAP_ALIAS]; break;
- case K_DOMAIN: q = &queries[LDAP_DOMAIN]; break;
- case K_CREDENTIALS: q = &queries[LDAP_CREDENTIALS]; break;
- case K_NETADDR: q = &queries[LDAP_NETADDR]; break;
- case K_USERINFO: q = &queries[LDAP_USERINFO]; break;
- case K_SOURCE: q = &queries[LDAP_SOURCE]; break;
- case K_MAILADDR: q = &queries[LDAP_MAILADDR]; break;
- case K_ADDRNAME: q = &queries[LDAP_ADDRNAME]; break;
- default:
- return (-1);
- }
-
- if (snprintf(filter, sizeof(filter), q->filter, key)
- >= (int)sizeof(filter)) {
- log_warnx("warn: table-ldap: filter too large");
- return (-1);
- }
-
- memset(res, 0, sizeof(res));
- ret = ldap_query(filter, q->attrs, res, q->attrn);
- if (ret <= 0 || dst == NULL)
- goto end;
-
- switch (type) {
-
- case K_ALIAS:
- memset(dst, 0, sz);
- for (i = 0; res[0][i]; i++) {
- if (i && strlcat(dst, ", ", sz) >= sz) {
- ret = -1;
- break;
- }
- if (strlcat(dst, res[0][i], sz) >= sz) {
- ret = -1;
- break;
- }
- }
- break;
- case K_DOMAIN:
- case K_MAILADDR:
- if (strlcpy(dst, res[0][0], sz) >= sz)
- ret = -1;
- break;
- case K_CREDENTIALS:
- if (snprintf(dst, sz, "%s:%s", res[0][0], res[1][0]) >= (int)sz)
- ret = -1;
- break;
- case K_USERINFO:
- if (snprintf(dst, sz, "%s:%s:%s", res[0][0], res[1][0],
- res[2][0]) >= (int)sz)
- ret = -1;
- break;
- default:
- log_warnx("warn: table-ldap: unsupported lookup kind");
- ret = -1;
- }
-
- if (ret == -1)
- log_warnx("warn: table-ldap: could not format result");
-
-end:
- for (i = 0; i < q->attrn; ++i)
- if (res[i])
- aldap_free_attr(res[i]);
-
- return (ret);
-}
diff --git a/usr.sbin/smtpd/table_passwd.5 b/usr.sbin/smtpd/table_passwd.5
deleted file mode 100644
index 847324e98cd..00000000000
--- a/usr.sbin/smtpd/table_passwd.5
+++ /dev/null
@@ -1,64 +0,0 @@
-.\" $OpenBSD: table_passwd.5,v 1.2 2014/02/04 17:47:02 jmc Exp $
-.\"
-.\" Copyright (c) 2014 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.
-.\"
-.\"
-.Dd $Mdocdate: February 4 2014 $
-.Dt TABLE_PASSWD 5
-.Os
-.Sh NAME
-.Nm table_passwd
-.Nd format description for smtpd passwd tables
-.Sh DESCRIPTION
-This manual page documents the file format of "passwd" tables used by the
-.Xr smtpd 8
-mail daemon.
-.Pp
-The format described here applies to tables as defined in
-.Xr smtpd.conf 5 .
-.Sh PASSWD TABLE
-A "passwd" table stores information regarding local users.
-The information is encoded using the traditional
-.Xr passwd 5
-format and allows the sharing of a user database across different software
-supporting this format.
-.Pp
-The table is used by
-.Xr smtpd 8
-when authenticating a user or when user information such as user-id or
-home directory is required for a delivery.
-.Pp
-A "passwd" table consists of a flat file containing the user entries, each
-one on a line by itself, with fields separated by a colon:
-.Bd -literal -offset indent
-gilles:*:1000:1000:Gilles:/home/gilles:/sbin/nologin
-eric:*:1001:1001:Eric:/home/eric:/sbin/nologin
-chl:*:1002:1002:Charles:/home/chl:/sbin/nologin
-.Ed
-.Pp
-If the table is used for authentication, the second field may contain a
-password encrypted using the
-.Xr crypt 3
-function.
-Such passwords can be generated using the
-.Xr encrypt 1
-utility or
-.Xr smtpctl 8
-encrypt command.
-.Sh SEE ALSO
-.Xr passwd 5 ,
-.Xr smtpd.conf 5 ,
-.Xr smtpctl 8 ,
-.Xr smtpd 8
diff --git a/usr.sbin/smtpd/table_passwd.c b/usr.sbin/smtpd/table_passwd.c
deleted file mode 100644
index 7cef61a83e4..00000000000
--- a/usr.sbin/smtpd/table_passwd.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* $OpenBSD: table_passwd.c,v 1.11 2015/10/11 12:50:00 sunil Exp $ */
-
-/*
- * Copyright (c) 2013 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 <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <err.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "smtpd-defines.h"
-#include "smtpd-api.h"
-#include "log.h"
-
-static int table_passwd_update(void);
-static int table_passwd_check(int, struct dict *, const char *);
-static int table_passwd_lookup(int, struct dict *, const char *, char *, size_t);
-static int table_passwd_fetch(int, struct dict *, char *, size_t);
-static int parse_passwd_entry(struct passwd *, char *);
-
-static char *config;
-static struct dict *passwd;
-
-int
-main(int argc, char **argv)
-{
- int ch;
-
- log_init(1);
-
- while ((ch = getopt(argc, argv, "")) != -1) {
- switch (ch) {
- default:
- log_warnx("warn: table-passwd: bad option");
- return (1);
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- log_warnx("warn: table-passwd: bogus argument(s)");
- return (1);
- }
-
- config = argv[0];
-
- if (table_passwd_update() == 0) {
- log_warnx("warn: table-passwd: error parsing config file");
- return (1);
- }
-
- table_api_on_update(table_passwd_update);
- table_api_on_check(table_passwd_check);
- table_api_on_lookup(table_passwd_lookup);
- table_api_on_fetch(table_passwd_fetch);
- table_api_dispatch();
-
- return (0);
-}
-
-static int
-table_passwd_update(void)
-{
- FILE *fp;
- char *buf = NULL, *p;
- char tmp[LINE_MAX];
- size_t sz = 0;
- ssize_t len;
- char *line;
- struct passwd pw;
- struct dict *npasswd;
-
- /* Parse configuration */
- fp = fopen(config, "r");
- if (fp == NULL)
- return (0);
-
- npasswd = calloc(1, sizeof *passwd);
- if (npasswd == NULL)
- goto err;
-
- dict_init(npasswd);
-
- while ((len = getline(&buf, &sz, fp)) != -1) {
- if (buf[len - 1] == '\n')
- buf[len - 1] = '\0';
-
- if (strlcpy(tmp, buf, sizeof tmp) >= sizeof tmp) {
- log_warnx("warn: table-passwd: line too long");
- goto err;
- }
- if (! parse_passwd_entry(&pw, tmp)) {
- log_warnx("warn: table-passwd: invalid entry");
- goto err;
- }
- if ((line = strdup(buf)) == NULL)
- err(1, NULL);
- dict_set(npasswd, pw.pw_name, line);
- }
- fclose(fp);
-
- /* swap passwd table and release old one*/
- if (passwd)
- while (dict_poproot(passwd, (void**)&p))
- free(p);
- passwd = npasswd;
-
- return (1);
-
-err:
- if (fp)
- fclose(fp);
- free(buf);
-
- /* release passwd table */
- if (npasswd) {
- while (dict_poproot(npasswd, (void**)&p))
- free(p);
- free(npasswd);
- }
- return (0);
-}
-
-static int
-table_passwd_check(int service, struct dict *params, const char *key)
-{
- return (-1);
-}
-
-static int
-table_passwd_lookup(int service, struct dict *params, const char *key, char *dst, size_t sz)
-{
- int r;
- struct passwd pw;
- char *line;
- char tmp[LINE_MAX];
-
- line = dict_get(passwd, key);
- if (line == NULL)
- return 0;
-
- (void)strlcpy(tmp, line, sizeof tmp);
- if (! parse_passwd_entry(&pw, tmp)) {
- log_warnx("warn: table-passwd: invalid entry");
- return -1;
- }
-
- r = 1;
- switch (service) {
- case K_CREDENTIALS:
- if (snprintf(dst, sz, "%s:%s",
- pw.pw_name, pw.pw_passwd) >= (ssize_t)sz) {
- log_warnx("warn: table-passwd: result too large");
- r = -1;
- }
- break;
- case K_USERINFO:
- if (snprintf(dst, sz, "%d:%d:%s",
- pw.pw_uid, pw.pw_gid, pw.pw_dir)
- >= (ssize_t)sz) {
- log_warnx("warn: table-passwd: result too large");
- r = -1;
- }
- break;
- default:
- log_warnx("warn: table-passwd: unknown service %d",
- service);
- r = -1;
- }
-
- return (r);
-}
-
-static int
-table_passwd_fetch(int service, struct dict *params, char *dst, size_t sz)
-{
- return (-1);
-}
-
-static int
-parse_passwd_entry(struct passwd *pw, char *buf)
-{
- const char *errstr;
- char *p, *q;
-
- p = buf;
-
- /* username */
- q = p;
- if ((p = strchr(q, ':')) == NULL)
- return 0;
- *p++ = 0;
- pw->pw_name = q;
-
- /* password */
- q = p;
- if ((p = strchr(q, ':')) == NULL)
- return 0;
- *p++ = 0;
- pw->pw_passwd = q;
-
- /* uid */
- q = p;
- if ((p = strchr(q, ':')) == NULL)
- return 0;
- *p++ = 0;
- pw->pw_uid = strtonum(q, 1, UID_MAX, &errstr);
- if (errstr)
- return 0;
-
- /* gid */
- q = p;
- if ((p = strchr(q, ':')) == NULL)
- return 0;
- *p++ = 0;
- pw->pw_gid = strtonum(q, 1, GID_MAX, &errstr);
- if (errstr)
- return 0;
-
- /* gecos */
- q = p;
- if ((p = strchr(q, ':')) == NULL)
- return 0;
- *p++ = 0;
- pw->pw_gecos = q;
-
- /* home */
- q = p;
- if ((p = strchr(q, ':')) == NULL)
- return 0;
- *p++ = 0;
- pw->pw_dir = q;
-
- /* shell */
- q = p;
- if (strchr(q, ':') != NULL)
- return 0;
- pw->pw_shell = q;
-
- return 1;
-}
diff --git a/usr.sbin/smtpd/table_sqlite.c b/usr.sbin/smtpd/table_sqlite.c
deleted file mode 100644
index f65be0e59bc..00000000000
--- a/usr.sbin/smtpd/table_sqlite.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/* $OpenBSD: table_sqlite.c,v 1.17 2015/10/11 12:50:00 sunil Exp $ */
-
-/*
- * Copyright (c) 2013 Eric Faurot <eric@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/socket.h>
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <ctype.h>
-#include <fcntl.h>
-#include <sqlite3.h>
-#include <stdio.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "smtpd-defines.h"
-#include "smtpd-api.h"
-#include "log.h"
-
-enum {
- SQL_ALIAS = 0,
- SQL_DOMAIN,
- SQL_CREDENTIALS,
- SQL_NETADDR,
- SQL_USERINFO,
- SQL_SOURCE,
- SQL_MAILADDR,
- SQL_ADDRNAME,
-
- SQL_MAX
-};
-
-static int table_sqlite_update(void);
-static int table_sqlite_lookup(int, struct dict *, const char *, char *, size_t);
-static int table_sqlite_check(int, struct dict *, const char *);
-static int table_sqlite_fetch(int, struct dict *, char *, size_t);
-
-static sqlite3_stmt *table_sqlite_query(const char *, int);
-
-#define DEFAULT_EXPIRE 60
-#define DEFAULT_REFRESH 1000
-
-static char *config;
-static sqlite3 *db;
-static sqlite3_stmt *statements[SQL_MAX];
-static sqlite3_stmt *stmt_fetch_source;
-static struct dict sources;
-static void *source_iter;
-static size_t source_refresh = 1000;
-static size_t source_ncall;
-static int source_expire = 60;
-static time_t source_update;
-
-int
-main(int argc, char **argv)
-{
- int ch;
-
- log_init(1);
- log_verbose(~0);
-
- while ((ch = getopt(argc, argv, "")) != -1) {
- switch (ch) {
- default:
- log_warnx("warn: table-sqlite: bad option");
- return (1);
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- log_warnx("warn: table-sqlite: bogus argument(s)");
- return (1);
- }
-
- config = argv[0];
-
- dict_init(&sources);
-
- if (table_sqlite_update() == 0) {
- log_warnx("warn: table-sqlite: error parsing config file");
- return (1);
- }
-
- table_api_on_update(table_sqlite_update);
- table_api_on_check(table_sqlite_check);
- table_api_on_lookup(table_sqlite_lookup);
- table_api_on_fetch(table_sqlite_fetch);
- table_api_dispatch();
-
- return (0);
-}
-
-static int
-table_sqlite_getconfstr(const char *key, const char *value, char **var)
-{
- if (*var) {
- log_warnx("warn: table-sqlite: duplicate %s %s", key, value);
- free(*var);
- }
- *var = strdup(value);
- if (*var == NULL) {
- log_warn("warn: table-sqlite: strdup");
- return (-1);
- }
- return (0);
-}
-
-static sqlite3_stmt *
-table_sqlite_prepare_stmt(sqlite3 *_db, const char *query, int ncols)
-{
- sqlite3_stmt *stmt;
-
- if (sqlite3_prepare_v2(_db, query, -1, &stmt, 0) != SQLITE_OK) {
- log_warnx("warn: table-sqlite: sqlite3_prepare_v2: %s",
- sqlite3_errmsg(_db));
- goto end;
- }
- if (sqlite3_column_count(stmt) != ncols) {
- log_warnx("warn: table-sqlite: columns: invalid columns count for query: %s", query);
- goto end;
- }
-
- return (stmt);
- end:
- sqlite3_finalize(stmt);
- return (NULL);
-}
-
-static int
-table_sqlite_update(void)
-{
- static const struct {
- const char *name;
- int cols;
- } qspec[SQL_MAX] = {
- { "query_alias", 1 },
- { "query_domain", 1 },
- { "query_credentials", 2 },
- { "query_netaddr", 1 },
- { "query_userinfo", 3 },
- { "query_source", 1 },
- { "query_mailaddr", 1 },
- { "query_addrname", 1 },
- };
- sqlite3 *_db;
- sqlite3_stmt *_statements[SQL_MAX];
- sqlite3_stmt *_stmt_fetch_source;
- char *_query_fetch_source;
- char *queries[SQL_MAX];
- ssize_t flen;
- size_t sz = 0, _source_refresh;
- int _source_expire;
- FILE *fp;
- char *key, *value, *buf = NULL, *dbpath;
- const char *e;
- int i, ret;
- long long ll;
-
- dbpath = NULL;
- _db = NULL;
- memset(queries, 0, sizeof(queries));
- memset(_statements, 0, sizeof(_statements));
- _query_fetch_source = NULL;
- _stmt_fetch_source = NULL;
-
- _source_refresh = DEFAULT_REFRESH;
- _source_expire = DEFAULT_EXPIRE;
-
- ret = 0;
-
- /* Parse configuration */
-
- fp = fopen(config, "r");
- if (fp == NULL)
- return (0);
-
- while ((flen = getline(&buf, &sz, fp)) != -1) {
- if (buf[flen - 1] == '\n')
- buf[flen - 1] = '\0';
-
- key = buf;
- while (isspace((unsigned char)*key))
- ++key;
- if (*key == '\0' || *key == '#')
- continue;
- value = key;
- strsep(&value, " \t:");
- if (value) {
- while (*value) {
- if (!isspace((unsigned char)*value) &&
- !(*value == ':' && isspace((unsigned char)*(value + 1))))
- break;
- ++value;
- }
- if (*value == '\0')
- value = NULL;
- }
-
- if (value == NULL) {
- log_warnx("warn: table-sqlite: missing value for key %s", key);
- continue;
- }
-
- if (!strcmp("dbpath", key)) {
- if (table_sqlite_getconfstr(key, value, &dbpath) == -1)
- goto end;
- continue;
- }
- if (!strcmp("fetch_source", key)) {
- if (table_sqlite_getconfstr(key, value, &_query_fetch_source) == -1)
- goto end;
- continue;
- }
- if (!strcmp("fetch_source_expire", key)) {
- e = NULL;
- ll = strtonum(value, 0, INT_MAX, &e);
- if (e) {
- log_warnx("warn: table-sqlite: bad value for %s: %s", key, e);
- goto end;
- }
- _source_expire = ll;
- continue;
- }
- if (!strcmp("fetch_source_refresh", key)) {
- e = NULL;
- ll = strtonum(value, 0, INT_MAX, &e);
- if (e) {
- log_warnx("warn: table-sqlite: bad value for %s: %s", key, e);
- goto end;
- }
- _source_refresh = ll;
- continue;
- }
-
- for(i = 0; i < SQL_MAX; i++)
- if (!strcmp(qspec[i].name, key))
- break;
- if (i == SQL_MAX) {
- log_warnx("warn: table-sqlite: bogus key %s", key);
- continue;
- }
-
- if (queries[i]) {
- log_warnx("warn: table-sqlite: duplicate key %s", key);
- continue;
- }
-
- queries[i] = strdup(value);
- if (queries[i] == NULL) {
- log_warnx("warn: table-sqlite: strdup");
- goto end;
- }
- }
-
- /* Setup db */
-
- log_debug("debug: table-sqlite: opening %s", dbpath);
-
- if (sqlite3_open(dbpath, &_db) != SQLITE_OK) {
- log_warnx("warn: table-sqlite: open: %s",
- sqlite3_errmsg(_db));
- goto end;
- }
-
- for (i = 0; i < SQL_MAX; i++) {
- if (queries[i] == NULL)
- continue;
- if ((_statements[i] = table_sqlite_prepare_stmt(_db, queries[i], qspec[i].cols)) == NULL)
- goto end;
- }
-
- if (_query_fetch_source &&
- (_stmt_fetch_source = table_sqlite_prepare_stmt(_db, _query_fetch_source, 1)) == NULL)
- goto end;
-
- /* Replace previous setup */
-
- for (i = 0; i < SQL_MAX; i++) {
- if (statements[i])
- sqlite3_finalize(statements[i]);
- statements[i] = _statements[i];
- _statements[i] = NULL;
- }
- if (stmt_fetch_source)
- sqlite3_finalize(stmt_fetch_source);
- stmt_fetch_source = _stmt_fetch_source;
- _stmt_fetch_source = NULL;
-
- if (db)
- sqlite3_close(_db);
- db = _db;
- _db = NULL;
-
- source_update = 0; /* force update */
- source_expire = _source_expire;
- source_refresh = _source_refresh;
-
- log_debug("debug: table-sqlite: config successfully updated");
- ret = 1;
-
- end:
-
- /* Cleanup */
- for (i = 0; i < SQL_MAX; i++) {
- if (_statements[i])
- sqlite3_finalize(_statements[i]);
- free(queries[i]);
- }
- if (_db)
- sqlite3_close(_db);
-
- free(dbpath);
- free(_query_fetch_source);
-
- free(buf);
- fclose(fp);
- return (ret);
-}
-
-static sqlite3_stmt *
-table_sqlite_query(const char *key, int service)
-{
- int i;
- sqlite3_stmt *stmt;
-
- stmt = NULL;
- for(i = 0; i < SQL_MAX; i++)
- if (service == (1 << i)) {
- stmt = statements[i];
- break;
- }
-
- if (stmt == NULL)
- return (NULL);
-
- if (sqlite3_bind_text(stmt, 1, key, strlen(key), NULL) != SQLITE_OK) {
- log_warnx("warn: table-sqlite: sqlite3_bind_text: %s",
- sqlite3_errmsg(db));
- return (NULL);
- }
-
- return (stmt);
-}
-
-static int
-table_sqlite_check(int service, struct dict *params, const char *key)
-{
- sqlite3_stmt *stmt;
- int r;
-
- stmt = table_sqlite_query(key, service);
- if (stmt == NULL)
- return (-1);
-
- r = sqlite3_step(stmt);
- sqlite3_reset(stmt);
-
- if (r == SQLITE_ROW)
- return (1);
-
- if (r == SQLITE_DONE)
- return (0);
-
- return (-1);
-}
-
-static int
-table_sqlite_lookup(int service, struct dict *params, const char *key, char *dst, size_t sz)
-{
- sqlite3_stmt *stmt;
- const char *value;
- int r, s;
-
- stmt = table_sqlite_query(key, service);
- if (stmt == NULL)
- return (-1);
-
- s = sqlite3_step(stmt);
- if (s == SQLITE_DONE) {
- sqlite3_reset(stmt);
- return (0);
- }
-
- if (s != SQLITE_ROW) {
- log_warnx("warn: table-sqlite: sqlite3_step: %s",
- sqlite3_errmsg(db));
- sqlite3_reset(stmt);
- return (-1);
- }
-
- r = 1;
-
- switch(service) {
- case K_ALIAS:
- memset(dst, 0, sz);
- do {
- value = sqlite3_column_text(stmt, 0);
- if (dst[0] && strlcat(dst, ", ", sz) >= sz) {
- log_warnx("warn: table-sqlite: result too large");
- r = -1;
- break;
- }
- if (strlcat(dst, value, sz) >= sz) {
- log_warnx("warn: table-sqlite: result too large");
- r = -1;
- break;
- }
- s = sqlite3_step(stmt);
- } while (s == SQLITE_ROW);
- if (s != SQLITE_ROW && s != SQLITE_DONE) {
- log_warnx("warn: table-sqlite: sqlite3_step: %s",
- sqlite3_errmsg(db));
- r = -1;
- }
- break;
- case K_CREDENTIALS:
- if (snprintf(dst, sz, "%s:%s",
- sqlite3_column_text(stmt, 0),
- sqlite3_column_text(stmt, 1)) >= (ssize_t)sz) {
- log_warnx("warn: table-sqlite: result too large");
- r = -1;
- }
- break;
- case K_USERINFO:
- if (snprintf(dst, sz, "%d:%d:%s",
- sqlite3_column_int(stmt, 0),
- sqlite3_column_int(stmt, 1),
- sqlite3_column_text(stmt, 2)) >= (ssize_t)sz) {
- log_warnx("warn: table-sqlite: result too large");
- r = -1;
- }
- break;
- case K_DOMAIN:
- case K_NETADDR:
- case K_SOURCE:
- case K_MAILADDR:
- case K_ADDRNAME:
- if (strlcpy(dst, sqlite3_column_text(stmt, 0), sz) >= sz) {
- log_warnx("warn: table-sqlite: result too large");
- r = -1;
- }
- break;
- default:
- log_warnx("warn: table-sqlite: unknown service %d", service);
- r = -1;
- }
-
- sqlite3_reset(stmt);
- return (r);
-}
-
-static int
-table_sqlite_fetch(int service, struct dict *params, char *dst, size_t sz)
-{
- const char *k;
- int s;
-
- if (service != K_SOURCE)
- return (-1);
-
- if (stmt_fetch_source == NULL)
- return (-1);
-
- if (source_ncall < source_refresh &&
- time(NULL) - source_update < source_expire)
- goto fetch;
-
- source_iter = NULL;
- while (dict_poproot(&sources, NULL))
- ;
-
- while ((s = sqlite3_step(stmt_fetch_source)) == SQLITE_ROW)
- dict_set(&sources, sqlite3_column_text(stmt_fetch_source, 0), NULL);
-
- if (s != SQLITE_DONE)
- log_warnx("warn: table-sqlite: sqlite3_step: %s",
- sqlite3_errmsg(db));
-
- sqlite3_reset(stmt_fetch_source);
-
- source_update = time(NULL);
- source_ncall = 0;
-
- fetch:
-
- source_ncall += 1;
-
- if (! dict_iter(&sources, &source_iter, &k, (void **)NULL)) {
- source_iter = NULL;
- if (! dict_iter(&sources, &source_iter, &k, (void **)NULL))
- return (0);
- }
-
- if (strlcpy(dst, k, sz) >= sz)
- return (-1);
-
- return (1);
-}