aboutsummaryrefslogtreecommitdiffstats
path: root/smtpd/makemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'smtpd/makemap.c')
-rw-r--r--smtpd/makemap.c521
1 files changed, 0 insertions, 521 deletions
diff --git a/smtpd/makemap.c b/smtpd/makemap.c
deleted file mode 100644
index 10e3f555..00000000
--- a/smtpd/makemap.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/* $OpenBSD: makemap.c,v 1.73 2020/02/24 16:16:07 millert Exp $ */
-
-/*
- * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
- * Copyright (c) 2008-2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "includes.h"
-
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h> /* Needed for flock */
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/tree.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <ctype.h>
-#ifdef HAVE_DB_H
-#include <db.h>
-#elif defined(HAVE_DB1_DB_H)
-#include <db1/db.h>
-#elif defined(HAVE_DB_185_H)
-#include <db_185.h>
-#endif
-#include <err.h>
-#include <errno.h>
-#include <event.h>
-#include <fcntl.h>
-#include <imsg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <limits.h>
-#ifdef HAVE_UTIL_H
-#include <util.h>
-#endif
-#ifdef HAVE_LIBUTIL_H
-#include <libutil.h>
-#endif
-
-#include "smtpd.h"
-#include "log.h"
-
-#define PATH_ALIASES SMTPD_CONFDIR "/aliases"
-
-static void usage(void);
-static int parse_map(DB *, int *, char *);
-static int parse_entry(DB *, int *, char *, size_t, size_t);
-static int parse_mapentry(DB *, int *, char *, size_t, size_t);
-static int parse_setentry(DB *, int *, char *, size_t, size_t);
-static int make_plain(DBT *, char *);
-static int make_aliases(DBT *, char *);
-static char *conf_aliases(char *);
-static int dump_db(const char *, DBTYPE);
-
-char *source;
-static int mode;
-
-enum output_type {
- T_PLAIN,
- T_ALIASES,
- T_SET
-} type;
-
-/*
- * Stub functions so that makemap compiles using minimum object files.
- */
-int
-fork_proc_backend(const char *backend, const char *conf, const char *procname)
-{
- return (-1);
-}
-
-int
-makemap(int prog_mode, int argc, char *argv[])
-{
- struct stat sb;
- char dbname[PATH_MAX];
- DB *db;
- const char *opts;
- char *conf, *oflag = NULL;
- int ch, dbputs = 0, Uflag = 0;
- DBTYPE dbtype = DB_HASH;
- char *p;
- gid_t gid;
- int fd = -1;
-
- gid = getgid();
- if (setresgid(gid, gid, gid) == -1)
- err(1, "setresgid");
-
- if ((env = config_default()) == NULL)
- err(1, NULL);
-
- log_init(1, LOG_MAIL);
-
- mode = prog_mode;
- conf = CONF_FILE;
- type = T_PLAIN;
- opts = "b:C:d:ho:O:t:U";
- if (mode == P_NEWALIASES)
- opts = "f:h";
-
- while ((ch = getopt(argc, argv, opts)) != -1) {
- switch (ch) {
- case 'b':
- if (optarg && strcmp(optarg, "i") == 0)
- mode = P_NEWALIASES;
- break;
- case 'C':
- break; /* for compatibility */
- case 'd':
- if (strcmp(optarg, "hash") == 0)
- dbtype = DB_HASH;
- else if (strcmp(optarg, "btree") == 0)
- dbtype = DB_BTREE;
- else
- errx(1, "unsupported DB type '%s'", optarg);
- break;
- case 'f':
- conf = optarg;
- break;
- case 'o':
- oflag = optarg;
- break;
- case 'O':
- if (strncmp(optarg, "AliasFile=", 10) != 0)
- break;
- type = T_ALIASES;
- p = strchr(optarg, '=');
- source = ++p;
- break;
- case 't':
- if (strcmp(optarg, "aliases") == 0)
- type = T_ALIASES;
- else if (strcmp(optarg, "set") == 0)
- type = T_SET;
- else
- errx(1, "unsupported type '%s'", optarg);
- break;
- case 'U':
- Uflag = 1;
- break;
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- /* sendmail-compat makemap ... re-execute using proper interface */
- if (argc == 2) {
- if (oflag)
- usage();
-
- p = strstr(argv[1], ".db");
- if (p == NULL || strcmp(p, ".db") != 0) {
- if (!bsnprintf(dbname, sizeof dbname, "%s.db",
- argv[1]))
- errx(1, "database name too long");
- }
- else {
- if (strlcpy(dbname, argv[1], sizeof dbname)
- >= sizeof dbname)
- errx(1, "database name too long");
- }
-
- execl(PATH_MAKEMAP, "makemap", "-d", argv[0], "-o", dbname,
- "-", (char *)NULL);
- err(1, "execl");
- }
-
- if (mode == P_NEWALIASES) {
- if (geteuid())
- errx(1, "need root privileges");
- if (argc != 0)
- usage();
- type = T_ALIASES;
- if (source == NULL)
- source = conf_aliases(conf);
- } else {
- if (argc != 1)
- usage();
- source = argv[0];
- }
-
- if (Uflag)
- return dump_db(source, dbtype);
-
- if (oflag == NULL && asprintf(&oflag, "%s.db", source) == -1)
- err(1, "asprintf");
-
- if (strcmp(source, "-") != 0)
- if (stat(source, &sb) == -1)
- err(1, "stat: %s", source);
-
- if (!bsnprintf(dbname, sizeof(dbname), "%s.XXXXXXXXXXX", oflag))
- errx(1, "path too long");
- if ((fd = mkstemp(dbname)) == -1)
- err(1, "mkstemp");
-
- db = dbopen(dbname, O_TRUNC|O_RDWR, 0644, dbtype, NULL);
- if (db == NULL) {
- warn("dbopen: %s", dbname);
- goto bad;
- }
-
- if (strcmp(source, "-") != 0)
- if (fchmod(db->fd(db), sb.st_mode) == -1 ||
- fchown(db->fd(db), sb.st_uid, sb.st_gid) == -1) {
- warn("couldn't carry ownership and perms to %s",
- dbname);
- goto bad;
- }
-
- if (!parse_map(db, &dbputs, source))
- goto bad;
-
- if (db->close(db) == -1) {
- warn("dbclose: %s", dbname);
- goto bad;
- }
-
- /* force to disk before renaming over an existing file */
- if (fsync(fd) == -1) {
- warn("fsync: %s", dbname);
- goto bad;
- }
- if (close(fd) == -1) {
- fd = -1;
- warn("close: %s", dbname);
- goto bad;
- }
- fd = -1;
-
- if (rename(dbname, oflag) == -1) {
- warn("rename");
- goto bad;
- }
-
- if (mode == P_NEWALIASES)
- printf("%s: %d aliases\n", source, dbputs);
- else if (dbputs == 0)
- warnx("warning: empty map created: %s", oflag);
-
- return 0;
-bad:
- if (fd != -1)
- close(fd);
- unlink(dbname);
- return 1;
-}
-
-static int
-parse_map(DB *db, int *dbputs, char *filename)
-{
- FILE *fp;
- char *line;
- size_t len;
- size_t lineno = 0;
-
- if (strcmp(filename, "-") == 0)
- fp = fdopen(0, "r");
- else
- fp = fopen(filename, "r");
- if (fp == NULL) {
- warn("%s", filename);
- return 0;
- }
-
- if (!isatty(fileno(fp)) && flock(fileno(fp), LOCK_SH|LOCK_NB) == -1) {
- if (errno == EWOULDBLOCK)
- warnx("%s is locked", filename);
- else
- warn("%s: flock", filename);
- fclose(fp);
- return 0;
- }
-
- while ((line = fparseln(fp, &len, &lineno,
- NULL, FPARSELN_UNESCCOMM)) != NULL) {
- if (!parse_entry(db, dbputs, line, len, lineno)) {
- free(line);
- fclose(fp);
- return 0;
- }
- free(line);
- }
-
- fclose(fp);
- return 1;
-}
-
-static int
-parse_entry(DB *db, int *dbputs, char *line, size_t len, size_t lineno)
-{
- switch (type) {
- case T_PLAIN:
- case T_ALIASES:
- return parse_mapentry(db, dbputs, line, len, lineno);
- case T_SET:
- return parse_setentry(db, dbputs, line, len, lineno);
- }
- return 0;
-}
-
-static int
-parse_mapentry(DB *db, int *dbputs, char *line, size_t len, size_t lineno)
-{
- DBT key;
- DBT val;
- char *keyp;
- char *valp;
-
- keyp = line;
- while (isspace((unsigned char)*keyp))
- keyp++;
- if (*keyp == '\0')
- return 1;
-
- valp = keyp;
- strsep(&valp, " \t:");
- if (valp == NULL || valp == keyp)
- goto bad;
- while (*valp == ':' || isspace((unsigned char)*valp))
- valp++;
- if (*valp == '\0')
- goto bad;
-
- /* Check for dups. */
- key.data = keyp;
- key.size = strlen(keyp) + 1;
-
- xlowercase(key.data, key.data, strlen(key.data) + 1);
- if (db->get(db, &key, &val, 0) == 0) {
- warnx("%s:%zd: duplicate entry for %s", source, lineno, keyp);
- return 0;
- }
-
- if (type == T_PLAIN) {
- if (!make_plain(&val, valp))
- goto bad;
- }
- else if (type == T_ALIASES) {
- if (!make_aliases(&val, valp))
- goto bad;
- }
-
- if (db->put(db, &key, &val, 0) == -1) {
- warn("dbput");
- return 0;
- }
-
- (*dbputs)++;
-
- free(val.data);
-
- return 1;
-
-bad:
- warnx("%s:%zd: invalid entry", source, lineno);
- return 0;
-}
-
-static int
-parse_setentry(DB *db, int *dbputs, char *line, size_t len, size_t lineno)
-{
- DBT key;
- DBT val;
- char *keyp;
-
- keyp = line;
- while (isspace((unsigned char)*keyp))
- keyp++;
- if (*keyp == '\0')
- return 1;
-
- val.data = "<set>";
- val.size = strlen(val.data) + 1;
-
- /* Check for dups. */
- key.data = keyp;
- key.size = strlen(keyp) + 1;
- xlowercase(key.data, key.data, strlen(key.data) + 1);
- if (db->get(db, &key, &val, 0) == 0) {
- warnx("%s:%zd: duplicate entry for %s", source, lineno, keyp);
- return 0;
- }
-
- if (db->put(db, &key, &val, 0) == -1) {
- warn("dbput");
- return 0;
- }
-
- (*dbputs)++;
-
- return 1;
-}
-
-static int
-make_plain(DBT *val, char *text)
-{
- val->data = xstrdup(text);
- val->size = strlen(text) + 1;
-
- return (val->size);
-}
-
-static int
-make_aliases(DBT *val, char *text)
-{
- struct expandnode xn;
- char *subrcpt;
- char *origtext;
-
- val->data = NULL;
- val->size = 0;
-
- origtext = xstrdup(text);
-
- while ((subrcpt = strsep(&text, ",")) != NULL) {
- /* subrcpt: strip initial and trailing whitespace. */
- subrcpt = strip(subrcpt);
- if (*subrcpt == '\0')
- goto error;
-
- if (!text_to_expandnode(&xn, subrcpt))
- goto error;
- }
-
- val->data = origtext;
- val->size = strlen(origtext) + 1;
- return (val->size);
-
-error:
- free(origtext);
-
- return 0;
-}
-
-static char *
-conf_aliases(char *cfgpath)
-{
- struct table *table;
- char *path;
- char *p;
-
- if (parse_config(env, cfgpath, 0))
- exit(1);
-
- table = table_find(env, "aliases");
- if (table == NULL)
- return (PATH_ALIASES);
-
- path = xstrdup(table->t_config);
- p = strstr(path, ".db");
- if (p == NULL || strcmp(p, ".db") != 0) {
- return (path);
- }
- *p = '\0';
- return (path);
-}
-
-static int
-dump_db(const char *dbname, DBTYPE dbtype)
-{
- DB *db;
- DBT key, val;
- char *keystr, *valstr;
- int r;
-
- db = dbopen(dbname, O_RDONLY, 0644, dbtype, NULL);
- if (db == NULL)
- err(1, "dbopen: %s", dbname);
-
- for (r = db->seq(db, &key, &val, R_FIRST); r == 0;
- r = db->seq(db, &key, &val, R_NEXT)) {
- keystr = key.data;
- valstr = val.data;
- if (keystr[key.size - 1] == '\0')
- key.size--;
- if (valstr[val.size - 1] == '\0')
- val.size--;
- printf("%.*s\t%.*s\n", (int)key.size, keystr,
- (int)val.size, valstr);
- }
- if (r == -1)
- err(1, "db->seq: %s", dbname);
-
- if (db->close(db) == -1)
- err(1, "dbclose: %s", dbname);
-
- return 0;
-}
-
-static void
-usage(void)
-{
- if (mode == P_NEWALIASES)
- fprintf(stderr, "usage: newaliases [-f file]\n");
- else
- fprintf(stderr, "usage: makemap [-U] [-d dbtype] [-o dbfile] "
- "[-t type] file\n");
- exit(1);
-}