summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2008-12-03 21:20:21 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2008-12-03 21:20:21 +0000
commitfdd64de839cb002b25846e837cdb6db5954a43aa (patch)
tree2332348baa5c6d209064d5e9e20ff653fe3917b9
parent5c8b09cd299f96f8f568a84fa004b7d8eed73fec (diff)
- smtpd's db maps are incompatible with sendmail's and needs a distinct
makemap utility, this is needed for virtual users support amongst other things. links to smtpd's aliases.c and only provides a frontent to parse map descriptions. contains code from pyr@, chl@ and I. Should have also been imported with smtpd.
-rw-r--r--usr.sbin/smtpd/makemap.856
-rw-r--r--usr.sbin/smtpd/makemap.c237
-rw-r--r--usr.sbin/smtpd/makemap/Makefile15
3 files changed, 308 insertions, 0 deletions
diff --git a/usr.sbin/smtpd/makemap.8 b/usr.sbin/smtpd/makemap.8
new file mode 100644
index 00000000000..73dbd53810e
--- /dev/null
+++ b/usr.sbin/smtpd/makemap.8
@@ -0,0 +1,56 @@
+.\" Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
+.\" All rights reserved.
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" By using this file, you agree to the terms and conditions set
+.\" forth in the LICENSE file which can be found at the top level of
+.\" the sendmail distribution.
+.\"
+.\"
+.\" $Sendmail: makemap.8,v 8.30 2002/06/27 23:41:04 gshapiro Exp $
+.\"
+.Dd October 21, 2008
+.Dt MAKEMAP 8
+.Os
+.Sh NAME
+.Nm makemap
+.Nd create database maps for smtpd
+.Sh SYNOPSIS
+.Nm makemap
+.Ar mapdesc
+.Sh DESCRIPTION
+.Nm
+creates the database maps used by the keyed map lookups in
+.Xr smtpd 8 .
+It reads input from the
+.Ar mapdesc
+file and outputs them to
+.Ar mapdesc.db .
+.Pp
+In all cases,
+.Nm
+reads lines from the standard input consisting of two
+words separated by whitespace.
+The first is the database key,
+the second is the value.
+.Pp
+Notice: do
+.Em not
+use
+.Nm
+to create the aliases data base, but
+.Xr newaliases 8
+as the input formats differ for historical reasons.
+.Sh SEE ALSO
+.Xr editmap 8 ,
+.Xr newaliases 8 ,
+.Xr smtpd 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Ox 4.5
+as a replacement for the
+.Nm
+command that was shipped with sendmail.
diff --git a/usr.sbin/smtpd/makemap.c b/usr.sbin/smtpd/makemap.c
new file mode 100644
index 00000000000..27841b43fa6
--- /dev/null
+++ b/usr.sbin/smtpd/makemap.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/tree.h>
+#include <sys/queue.h>
+#include <sys/param.h>
+
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <db.h>
+#include <err.h>
+#include <errno.h>
+#include <event.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "smtpd.h"
+
+extern char *__progname;
+
+static int usage(void);
+int parse_map(const char *);
+int parse_entry(char *, size_t, size_t);
+
+int alias_parse(struct alias *, char *, size_t);
+
+DB *db;
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ char pathname[MAXPATHLEN];
+ char dbname[MAXPATHLEN];
+ char output[MAXPATHLEN];
+
+ while ((ch = getopt(argc, argv, "")) != -1) {
+ switch (ch) {
+ default:
+ return usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ return usage();
+
+ bzero(pathname, MAXPATHLEN);
+ snprintf(pathname, MAXPATHLEN, "%s.XXXXX", argv[0]);
+ if (mkdtemp(pathname) == NULL)
+ errx(1, "failed to create temporary directory");
+
+ bzero(dbname, MAXPATHLEN);
+ snprintf(dbname, MAXPATHLEN, "%s/map", pathname);
+ db = dbopen(dbname, O_CREAT|O_EXLOCK|O_RDWR|O_SYNC, 0644, DB_HASH,
+ NULL);
+ if (db == NULL) {
+ warn("dbopen");
+ goto bad;
+ }
+
+ if (! parse_map(argv[0])) {
+ warnx("syntax error in aliases file");
+ goto bad;
+ }
+
+ db->close(db);
+
+ snprintf(output, MAXPATHLEN, "%s.db", argv[0]);
+
+ if (rename(dbname, output) == -1) {
+ warn("rename");
+ goto bad;
+ }
+
+ if (chmod(output, 0644) == -1)
+ err(1, "chmod");
+
+ if (rmdir(pathname) == -1)
+ err(1, "rmdir");
+
+ return EX_OK;
+bad:
+ if (dbname[0] != '\0')
+ if (unlink(dbname) == -1)
+ err(1, "unlink: %s", dbname);
+ if (rmdir(pathname) == -1)
+ err(1, "rmdir: %s", pathname);
+ return 1;
+}
+
+static int
+usage(void)
+{
+ fprintf(stderr, "usage: %s filename\n", __progname);
+ return EX_USAGE;
+}
+
+int
+parse_map(const char *filename)
+{
+ FILE *fp;
+ char *line;
+ size_t len;
+ size_t lineno = 0;
+ char delim[] = { '\\', '\\', '#' };
+
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ errx(1, "failed to open aliases file");
+
+
+ while ((line = fparseln(fp, &len, &lineno, delim, 0)) != NULL) {
+ if (len == 0)
+ continue;
+ parse_entry(line, len, lineno);
+ free(line);
+ }
+
+ fclose(fp);
+ return 1;
+}
+
+int
+parse_entry(char *line, size_t len, size_t lineno)
+{
+ char *name;
+ char *delim;
+ char *rcpt;
+ char *subrcpt;
+ struct alias alias;
+ int ret;
+ DBT key;
+ DBT val;
+
+ name = line;
+ while (*name && isspace(*name))
+ ++name;
+
+ rcpt = delim = strchr(name, ' ');
+ if (rcpt == NULL)
+ rcpt = delim = strchr(name, '\t');
+ if (rcpt == NULL || name == rcpt)
+ goto bad;
+
+
+ *delim-- = 0;
+ while (isspace(*delim))
+ *delim-- = '\0';
+ rcpt++;
+ while (*rcpt && isspace(*rcpt))
+ ++rcpt;
+ if (*rcpt == '\0')
+ goto bad;
+
+ /* At this point, name points to nul-terminate name */
+ for (; (subrcpt = strsep(&rcpt, ",")) != NULL;) {
+ while (*subrcpt && isspace(*subrcpt))
+ ++subrcpt;
+ if (*subrcpt == '\0')
+ continue;
+
+ delim = subrcpt + strlen(subrcpt);
+ delim--;
+ while (isspace(*delim))
+ *delim-- = '\0';
+
+ key.data = name;
+ key.size = strlen(name) + 1;
+
+ if ((ret = db->get(db, &key, &val, 0)) == -1)
+ errx(1, "db->get()");
+
+ if (ret == 1) {
+ val.data = NULL;
+ val.size = 0;
+ }
+
+ if (! alias_parse(&alias, subrcpt, strlen(subrcpt)))
+ goto bad;
+
+ if (val.size == 0) {
+ val.size = sizeof(struct alias);
+ val.data = &alias;
+
+ if ((ret = db->put(db, &key, &val, 0)) == -1)
+ errx(1, "db->get()");
+ }
+ else {
+ void *p;
+
+ p = calloc(val.size + sizeof(alias), 1);
+ if (p == NULL)
+ errx(1, "calloc: memory exhausted");
+ memcpy(p, val.data, val.size);
+ memcpy((u_int8_t *)p + val.size, &alias, sizeof(alias));
+
+ val.data = p;
+ val.size += sizeof(alias);
+
+ if ((ret = db->put(db, &key, &val, 0)) == -1)
+ errx(1, "db->get()");
+
+ free(p);
+ }
+ db->sync(db, 0);
+ }
+
+ return 1;
+
+bad:
+ warnx("line %zd: invalid entry: %s", lineno, line);
+ return 0;
+}
diff --git a/usr.sbin/smtpd/makemap/Makefile b/usr.sbin/smtpd/makemap/Makefile
new file mode 100644
index 00000000000..56c1a8654d8
--- /dev/null
+++ b/usr.sbin/smtpd/makemap/Makefile
@@ -0,0 +1,15 @@
+# $OpenBSD: Makefile,v 1.1 2008/12/03 21:20:20 gilles Exp $
+
+.PATH: ${.CURDIR}/..
+
+PROG= makemap
+BINOWN= root
+
+BINMODE?=555
+
+BINDIR= /usr/bin
+MAN= makemap.8
+
+SRCS= makemap.c aliases.c map.c log.c
+LDFLAGS= -lutil
+.include <bsd.prog.mk>