diff options
author | Gilles Chehade <gilles@cvs.openbsd.org> | 2008-12-03 21:20:21 +0000 |
---|---|---|
committer | Gilles Chehade <gilles@cvs.openbsd.org> | 2008-12-03 21:20:21 +0000 |
commit | fdd64de839cb002b25846e837cdb6db5954a43aa (patch) | |
tree | 2332348baa5c6d209064d5e9e20ff653fe3917b9 | |
parent | 5c8b09cd299f96f8f568a84fa004b7d8eed73fec (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.8 | 56 | ||||
-rw-r--r-- | usr.sbin/smtpd/makemap.c | 237 | ||||
-rw-r--r-- | usr.sbin/smtpd/makemap/Makefile | 15 |
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> |