summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilles Chehade <gilles@cvs.openbsd.org>2008-12-03 21:13:19 +0000
committerGilles Chehade <gilles@cvs.openbsd.org>2008-12-03 21:13:19 +0000
commit5c8b09cd299f96f8f568a84fa004b7d8eed73fec (patch)
tree9e7e2fe6b94b70addd5028cd9052527ed5c0fda5
parente93b0551c792b3193ed6ac05752f9add93926265 (diff)
smtpd's aliases db is incompatible with sendmail's and requires a distinct
newaliases utility. newaliases links to the aliases.c file from smtpd and only provides a frontend to parse aliases file. contains code from pyr@, chl@ and I, it should have been imported with smtpd.
-rw-r--r--usr.sbin/smtpd/newaliases.850
-rw-r--r--usr.sbin/smtpd/newaliases.c236
-rw-r--r--usr.sbin/smtpd/newaliases/Makefile15
3 files changed, 301 insertions, 0 deletions
diff --git a/usr.sbin/smtpd/newaliases.8 b/usr.sbin/smtpd/newaliases.8
new file mode 100644
index 00000000000..780a20f804f
--- /dev/null
+++ b/usr.sbin/smtpd/newaliases.8
@@ -0,0 +1,50 @@
+.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
+.\" All rights reserved.
+.\" Copyright (c) 1983, 1997 Eric P. Allman. All rights reserved.
+.\" Copyright (c) 1985, 1990, 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: newaliases.1,v 8.19 2001/10/10 03:23:17 ca Exp $
+.\"
+.Dd October 21, 2008
+.Dt NEWALIASES 8
+.Os
+.Sh NAME
+.Nm newaliases
+.Nd rebuild the data base for the mail aliases file
+.Sh SYNOPSIS
+.Nm newaliases
+.Sh DESCRIPTION
+.Nm
+rebuilds the random access data base for the mail aliases file
+.Pa /etc/mail/aliases .
+It must be run each time this file is changed
+in order for the change to take effect.
+.Pp
+The
+.Nm
+utility exits 0 on success, and >0 if an error occurs.
+.Sh FILES
+.Bl -tag -width /etc/mail/aliases -compact
+.It Pa /etc/mail/aliases
+The mail aliases file
+.El
+.Sh SEE ALSO
+.Xr aliases 5 ,
+.Xr mailer.conf 5 ,
+.Xr makemap 8 ,
+.Xr smtpd 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Ox 4.5
+as a replacement for the older
+.Nm
+utility that was shipped with
+.Xr sendmail .
diff --git a/usr.sbin/smtpd/newaliases.c b/usr.sbin/smtpd/newaliases.c
new file mode 100644
index 00000000000..6cfbe7c4f91
--- /dev/null
+++ b/usr.sbin/smtpd/newaliases.c
@@ -0,0 +1,236 @@
+/*
+ * 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_aliases(const char *);
+int parse_entry(char *, size_t, size_t);
+
+int alias_parse(struct alias *, char *, size_t);
+
+DB *db;
+static int dflag;
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ char pathname[MAXPATHLEN];
+ char dbname[MAXPATHLEN];
+
+ while ((ch = getopt(argc, argv, "dh")) != -1) {
+ switch (ch) {
+ case 'd':
+ dflag = 1;
+ break;
+ case 'h':
+ default:
+ return usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ return usage();
+
+ bzero(pathname, MAXPATHLEN);
+ snprintf(pathname, MAXPATHLEN, "/etc/mail/aliases.XXXXX");
+ if (mkdtemp(pathname) == NULL)
+ errx(1, "failed to create temporary directory");
+
+ bzero(dbname, MAXPATHLEN);
+ snprintf(dbname, MAXPATHLEN, "%s/aliases.db", 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_aliases(PATH_ALIASES)) {
+ warnx("syntax error in aliases file");
+ goto bad;
+ }
+
+ db->close(db);
+
+ if (rename(dbname, PATH_ALIASESDB) == -1) {
+ warn("rename");
+ goto bad;
+ }
+
+ if (chmod(PATH_ALIASESDB, 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_aliases(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 (name == rcpt)
+ goto bad;
+ *delim-- = 0;
+ rcpt++;
+ 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/newaliases/Makefile b/usr.sbin/smtpd/newaliases/Makefile
new file mode 100644
index 00000000000..467cff799fe
--- /dev/null
+++ b/usr.sbin/smtpd/newaliases/Makefile
@@ -0,0 +1,15 @@
+# $OpenBSD: Makefile,v 1.1 2008/12/03 21:13:18 gilles Exp $
+
+.PATH: ${.CURDIR}/..
+
+PROG= newaliases
+BINOWN= root
+
+BINMODE?=555
+
+BINDIR= /usr/bin
+MAN= newaliases.8
+
+SRCS= newaliases.c aliases.c map.c log.c
+LDFLAGS= -lutil
+.include <bsd.prog.mk>