diff options
| author | tron <tron@NetBSD.org> | 2000-02-07 20:05:21 +0000 |
|---|---|---|
| committer | tron <tron@NetBSD.org> | 2000-02-07 20:05:21 +0000 |
| commit | ea4809da9e5ffc8fa7b3b1803aa9d0f82d5f7691 (patch) | |
| tree | ea336267c58b2deef11f141c1f1dcfa78b945346 /gnu/dist/sendmail/makemap | |
| parent | 65b8f3b2eb2c9a7a37151dec23f22be342f0bdec (diff) | |
Initial import of "sendmail" 8.9.3 sources.
Diffstat (limited to 'gnu/dist/sendmail/makemap')
| -rw-r--r-- | gnu/dist/sendmail/makemap/Makefile.m4 | 110 | ||||
| -rw-r--r-- | gnu/dist/sendmail/makemap/makemap.0 | 63 | ||||
| -rw-r--r-- | gnu/dist/sendmail/makemap/makemap.8 | 127 | ||||
| -rw-r--r-- | gnu/dist/sendmail/makemap/makemap.c | 1016 |
4 files changed, 1316 insertions, 0 deletions
diff --git a/gnu/dist/sendmail/makemap/Makefile.m4 b/gnu/dist/sendmail/makemap/Makefile.m4 new file mode 100644 index 00000000000..983ffdf3ff8 --- /dev/null +++ b/gnu/dist/sendmail/makemap/Makefile.m4 @@ -0,0 +1,110 @@ +# +# This Makefile is designed to work on the old "make" program. +# +# @(#)Makefile.m4 8.21 (Berkeley) 7/12/1998 +# + +# C compiler +CC= confCC + +# Shell +SHELL= confSHELL + +# use O=-O (usual) or O=-g (debugging) +O= ifdef(`confOPTIMIZE', `confOPTIMIZE', `-O') + +# location of sendmail source directory +SRCDIR= ifdef(`confSRCDIR', `confSRCDIR', `../../src') + +# define the database mechanisms available for map & alias lookups: +# -DNDBM -- use new DBM +# -DNEWDB -- use new Berkeley DB +# The really old (V7) DBM library is no longer supported. +# +MAPDEF= ifdef(`confMAPDEF', `confMAPDEF') + +# environment definitions (e.g., -D_AIX3) +ENVDEF= -DNOT_SENDMAIL ifdef(`confENVDEF', `confENVDEF') + +# see also conf.h for additional compilation flags + +# include directories +INCDIRS=-I${SRCDIR} confINCDIRS + +# loader options +LDOPTS= ifdef(`confLDOPTS', `confLDOPTS') + +# library directories +LIBDIRS=confLIBDIRS + +# libraries required on your system +LIBS= ifdef(`confLIBS', `confLIBS') + +# location of makemap binary (usually /usr/sbin or /usr/etc) +SBINDIR=${DESTDIR}ifdef(`confSBINDIR', `confSBINDIR', `/usr/sbin') + +# additional .o files needed +OBJADD= ifdef(`confOBJADD', `confOBJADD') + +undivert(1) + +################### end of user configuration flags ###################### + +BUILDBIN=confBUILDBIN +COPTS= -I. ${INCDIRS} ${MAPDEF} ${ENVDEF} +CFLAGS= $O ${COPTS} + +BEFORE= confBEFORE safefile.c snprintf.c +OBJS= makemap.o safefile.o snprintf.o ${OBJADD} + +NROFF= ifdef(`confNROFF', `confNROFF', `groff -Tascii') +MANDOC= ifdef(`confMANDOC', `confMANDOC', `-mandoc') + +INSTALL=ifdef(`confINSTALL', `confINSTALL', `install') +BINOWN= ifdef(`confUBINOWN', `confUBINOWN', `bin') +BINGRP= ifdef(`confUBINGRP', `confUBINGRP', `bin') +BINMODE=ifdef(`confUBINMODE', `confUBINMODE', `555') + +MANOWN= ifdef(`confMANOWN', `confMANOWN', `bin') +MANGRP= ifdef(`confMANGRP', `confMANGRP', `bin') +MANMODE=ifdef(`confMANMODE', `confMANMODE', `444') + +MANROOT=${DESTDIR}ifdef(`confMANROOT', `confMANROOT', `/usr/share/man/cat') +MAN8= ${MANROOT}ifdef(`confMAN8', `confMAN8', `8') +MAN8EXT=ifdef(`confMAN8EXT', `confMAN8EXT', `8') +MAN8SRC=ifdef(`confMAN8SRC', `confMAN8SRC', `0') + +ALL= makemap makemap.${MAN8SRC} + +all: ${ALL} + +makemap: ${BEFORE} ${OBJS} + ${CC} -o makemap ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS} + +safefile.c: ${SRCDIR}/safefile.c + -ln -s ${SRCDIR}/safefile.c safefile.c + +snprintf.c: ${SRCDIR}/snprintf.c + -ln -s ${SRCDIR}/snprintf.c snprintf.c + +undivert(3) + +makemap.${MAN8SRC}: makemap.8 + ${NROFF} ${MANDOC} makemap.8 > makemap.${MAN8SRC} + +install: install-makemap install-docs + +install-makemap: makemap + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} makemap ${SBINDIR} + +install-docs: makemap.${MAN8SRC} +ifdef(`confNO_MAN_INSTALL', `dnl', +` ${INSTALL} -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} makemap.${MAN8SRC} ${MAN8}/makemap.${MAN8EXT}') + +clean: + rm -f ${OBJS} makemap makemap.${MAN8SRC} + +################ Dependency scripts +include(confBUILDTOOLSDIR/M4/depend/ifdef(`confDEPEND_TYPE', `confDEPEND_TYPE', +`generic').m4)dnl +################ End of dependency scripts diff --git a/gnu/dist/sendmail/makemap/makemap.0 b/gnu/dist/sendmail/makemap/makemap.0 new file mode 100644 index 00000000000..eb6cd778938 --- /dev/null +++ b/gnu/dist/sendmail/makemap/makemap.0 @@ -0,0 +1,63 @@ +MAKEMAP(8) BSD System Manager's Manual MAKEMAP(8) + +NNAAMMEE + mmaakkeemmaapp - create database maps for sendmail + +SSYYNNOOPPSSIISS + mmaakkeemmaapp [--NN] [--dd] [--ff] [--oo] [--rr] [--ss] [--vv] _m_a_p_t_y_p_e _m_a_p_n_a_m_e + +DDEESSCCRRIIPPTTIIOONN + mmaakkeemmaapp creates the database maps used by the keyed map lookups in + sendmail(8). It reads input from the standard input and outputs them to + the indicated _m_a_p_n_a_m_e. + + Depending on how it is compiled, mmaakkeemmaapp handles up to three different + database formats, selected using the _m_a_p_t_y_p_e parameter. They may be + + dbm DBM format maps. This requires the ndbm(3) library. + + btree B-Tree format maps. This requires the new Berkeley DB li- + brary. + + hash Hash format maps. This also requires the Berkeley DB li- + brary. + + In all cases, mmaakkeemmaapp reads lines from the standard input consisting of + two words separated by white space. The first is the database key, the + second is the value. The value may contain ``%_n'' strings to indicated + parameter substitution. Literal percents should be doubled (``%%''). + Blank lines and lines beginning with ``#'' are ignored. + + FFllaaggss + + --NN Include the null byte that terminates strings in the map. + This must match the -N flag in the sendmail.cf ``K'' line. + + --dd Allow duplicate keys in the map. This is only allowed on B- + Tree format maps. If two identical keys are read, they will + both be inserted into the map. + + --ff Normally all upper case letters in the key are folded to low- + er case. This flag disables that behaviour. This is intend- + ed to mesh with the -f flag in the KK line in sendmail.cf. + The value is never case folded. + + --oo Append to an old file. This allows you to augment an exist- + ing file. + + --rr Allow replacement of existing keys. Normally mmaakkeemmaapp com- + plains if you repeat a key, and does not do the insert. + + --ss Ignore safety checks on maps being created. This includes + checking for hard or symbolic links in world writable direc- + tories. + + --vv Verbosely print what it is doing. + +SSEEEE AALLSSOO + sendmail(8) + +HHIISSTTOORRYY + The mmaakkeemmaapp command appeared in 4.4BSD. + +4.4BSD November 16, 1992 1 diff --git a/gnu/dist/sendmail/makemap/makemap.8 b/gnu/dist/sendmail/makemap/makemap.8 new file mode 100644 index 00000000000..81f53a85b52 --- /dev/null +++ b/gnu/dist/sendmail/makemap/makemap.8 @@ -0,0 +1,127 @@ +.\" Copyright (c) 1998 Sendmail, Inc. 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. +.\" +.\" +.\" @(#)makemap.8 8.12 (Berkeley) 11/13/1998 +.\" +.Dd November 16, 1992 +.Dt MAKEMAP 8 +.Os BSD 4.4 +.Sh NAME +.Nm makemap +.Nd create database maps for sendmail +.Sh SYNOPSIS +.Nm +.Op Fl N +.if \nP .Op Fl c Ar cachesize +.Op Fl d +.Op Fl f +.if \nP .Op Fl l +.Op Fl o +.Op Fl r +.Op Fl s +.Op Fl v +.Ar maptype +.Ar mapname +.Sh DESCRIPTION +.Nm +creates the database maps used by the keyed map lookups in +.Xr sendmail 8 . +It reads input from the standard input +and outputs them to the indicated +.Ar mapname . +.Pp +Depending on how it is compiled, +.Nm +handles up to three different database formats, +selected using the +.Ar maptype +parameter. +They may be +.Bl -tag -width Fl +.It Li dbm +DBM format maps. +This requires the +.Xr ndbm 3 +library. +.It Li btree +B-Tree format maps. +This requires the new Berkeley DB +library. +.It Li hash +Hash format maps. +This also requires the Berkeley DB +library. +.El +.Pp +In all cases, +.Nm +reads lines from the standard input consisting of two +words separated by white space. +The first is the database key, +the second is the value. +The value may contain +``%\fIn\fP'' +strings to indicated parameter substitution. +Literal percents should be doubled +(``%%''). +Blank lines and lines beginning with ``#'' are ignored. +.Ss Flags +.Bl -tag -width Fl +.It Fl N +Include the null byte that terminates strings +in the map. +This must match the \-N flag in the sendmail.cf +``K'' line. +.if \nP \ +\{\ +.It Fl c +Use the specified hash and B-Tree cache size. +.\} +.It Fl d +Allow duplicate keys in the map. +This is only allowed on B-Tree format maps. +If two identical keys are read, +they will both be inserted into the map. +.It Fl f +Normally all upper case letters in the key +are folded to lower case. +This flag disables that behaviour. +This is intended to mesh with the +\-f flag in the +\fBK\fP +line in sendmail.cf. +The value is never case folded. +.if \nP \ +\{\ +.It Fl l +List supported map types. +.\} +.It Fl o +Append to an old file. +This allows you to augment an existing file. +.It Fl r +Allow replacement of existing keys. +Normally +.Nm +complains if you repeat a key, +and does not do the insert. +.It Fl s +Ignore safety checks on maps being created. +This includes checking for hard or symbolic +links in world writable directories. +.It Fl v +Verbosely print what it is doing. +.El +.Sh SEE ALSO +.Xr sendmail 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.4 . diff --git a/gnu/dist/sendmail/makemap/makemap.c b/gnu/dist/sendmail/makemap/makemap.c new file mode 100644 index 00000000000..aaaba32a57a --- /dev/null +++ b/gnu/dist/sendmail/makemap/makemap.c @@ -0,0 +1,1016 @@ +/* + * Copyright (c) 1998 Sendmail, Inc. All rights reserved. + * Copyright (c) 1992 Eric P. Allman. All rights reserved. + * Copyright (c) 1992, 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. + * + */ + +#ifndef lint +static char sccsid[] = "@(#)makemap.c 8.71 (Berkeley) 11/29/1998"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/errno.h> +#ifndef ISC_UNIX +# include <sys/file.h> +#endif +#include "sendmail.h" +#include "pathnames.h" + +#ifdef NDBM +# include <ndbm.h> +#endif + +#ifdef NEWDB +# include <db.h> +# ifndef DB_VERSION_MAJOR +# define DB_VERSION_MAJOR 1 +# endif +#endif + +enum type { T_DBM, T_BTREE, T_HASH, T_ERR, T_UNKNOWN }; + +union dbent +{ +#ifdef NDBM + datum dbm; +#endif +#ifdef NEWDB + DBT db; +#endif + struct + { + char *data; + size_t size; + } xx; +}; + +uid_t RealUid; +gid_t RealGid; +char *RealUserName; +uid_t RunAsUid; +uid_t RunAsGid; +char *RunAsUserName; +int Verbose = 2; +bool DontInitGroups = FALSE; +long DontBlameSendmail = DBS_SAFE; +u_char tTdvect[100]; +uid_t TrustedUid = 0; + +#define BUFSIZE 1024 + +int +main(argc, argv) + int argc; + char **argv; +{ + char *progname; + char *cfile; + bool inclnull = FALSE; + bool notrunc = FALSE; + bool allowreplace = FALSE; + bool allowdups = FALSE; + bool verbose = FALSE; + bool foldcase = TRUE; + int exitstat; + int opt; + char *typename = NULL; + char *mapname = NULL; + char *ext = NULL; + int lineno; + int st; + int mode; + int putflags = 0; +#ifdef NEWDB + long dbcachesize = 1024 * 1024; +#endif + enum type type; +#if !O_EXLOCK + int fd; +#endif + int sff = SFF_ROOTOK|SFF_REGONLY; + struct passwd *pw; + union + { +#ifdef NDBM + DBM *dbm; +#endif +#ifdef NEWDB + DB *db; +#endif + void *dbx; + } dbp; + union dbent key, val; +#ifdef NEWDB +# if DB_VERSION_MAJOR < 2 + BTREEINFO bti; + HASHINFO hinfo; +# else + DB_INFO dbinfo; +# endif +#endif + char ibuf[BUFSIZE]; + char fbuf[MAXNAME]; + char dbuf[MAXNAME]; +#ifdef NDBM + char pbuf[MAXNAME]; +#endif +#if _FFR_TRUSTED_USER + FILE *cfp; + char buf[MAXLINE]; +#endif + static char rnamebuf[MAXNAME]; /* holds RealUserName */ + struct stat std; +#ifdef NDBM + struct stat stp; +#endif + extern char *optarg; + extern int optind; + + progname = argv[0]; + cfile = _PATH_SENDMAILCF; + + RunAsUid = RealUid = getuid(); + RunAsGid = RealGid = getgid(); + pw = getpwuid(RealUid); + if (pw != NULL) + { + if (strlen(pw->pw_name) > MAXNAME - 1) + pw->pw_name[MAXNAME] = 0; + sprintf(rnamebuf, "%s", pw->pw_name); + } + else + sprintf(rnamebuf, "Unknown UID %d", (int) RealUid); + RunAsUserName = RealUserName = rnamebuf; + +#if _FFR_NEW_MAKEMAP_FLAGS +#define OPTIONS "C:Nc:dflorsv" +#else +#define OPTIONS "C:Ndforsv" +#endif + while ((opt = getopt(argc, argv, OPTIONS)) != EOF) + { + switch (opt) + { + case 'C': + cfile = optarg; + break; + + case 'N': + inclnull = TRUE; + break; + +#if _FFR_NEW_MAKEMAP_FLAGS + case 'c': +# ifdef NEWDB + dbcachesize = atol(optarg); +# endif + break; +#endif + + case 'd': + allowdups = TRUE; + break; + + case 'f': + foldcase = FALSE; + break; + +#if _FFR_NEW_MAKEMAP_FLAGS + case 'l': +# ifdef NDBM + printf("dbm\n"); +# endif +# ifdef NEWDB + printf("hash\n"); + printf("btree\n"); +# endif + exit(EX_OK); + break; +#endif + + case 'o': + notrunc = TRUE; + break; + + case 'r': + allowreplace = TRUE; + break; + + case 's': + DontBlameSendmail |= DBS_MAPINUNSAFEDIRPATH|DBS_WRITEMAPTOHARDLINK|DBS_WRITEMAPTOSYMLINK|DBS_LINKEDMAPINWRITABLEDIR; + break; + + case 'v': + verbose = TRUE; + break; + + default: + type = T_ERR; + break; + } + } + + if (!bitset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) + sff |= SFF_NOSLINK; + if (!bitset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) + sff |= SFF_NOHLINK; + if (!bitset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) + sff |= SFF_NOWLINK; + + argc -= optind; + argv += optind; + if (argc != 2) + type = T_ERR; + else + { + typename = argv[0]; + mapname = argv[1]; + ext = NULL; + + if (strcmp(typename, "dbm") == 0) + { + type = T_DBM; + } + else if (strcmp(typename, "btree") == 0) + { + type = T_BTREE; + ext = ".db"; + } + else if (strcmp(typename, "hash") == 0) + { + type = T_HASH; + ext = ".db"; + } + else + type = T_UNKNOWN; + } + +#if _FFR_TRUSTED_USER + if ((cfp = fopen(cfile, "r")) == NULL) + { + fprintf(stderr, "mailstats: "); + perror(cfile); + exit(EX_NOINPUT); + } + while (fgets(buf, sizeof(buf), cfp) != NULL) + { + register char *b; + + if ((b = strchr(buf, '\n')) != NULL) + *b = '\0'; + + b = buf; + switch (*b++) + { + case 'O': /* option */ + if (strncasecmp(b, " TrustedUser", 12) == 0 && + !(isascii(b[12]) && isalnum(b[12]))) + { + b = strchr(b, '='); + if (b == NULL) + continue; + while (isascii(*++b) && isspace(*b)) + continue; + if (isascii(*b) && isdigit(*b)) + TrustedUid = atoi(b); + else + { + register struct passwd *pw; + + TrustedUid = 0; + pw = getpwnam(b); + if (pw == NULL) + fprintf(stderr, + "TrustedUser: unknown user %s\n", b); + else + TrustedUid = pw->pw_uid; + } + +# ifdef UID_MAX + if (TrustedUid > UID_MAX) + { + syserr("TrustedUser: uid value (%ld) > UID_MAX (%ld)", + TrustedUid, UID_MAX); + TrustedUid = 0; + } +# endif + break; + } + + + default: + continue; + } + } + (void) fclose(cfp); +#endif + switch (type) + { + case T_ERR: +#if _FFR_NEW_MAKEMAP_FLAGS + fprintf(stderr, + "Usage: %s [-N] [-c cachesize] [-d] [-f] [-l] [-o] [-r] [-s] [-v] type mapname\n", + progname); +#else + fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-s] [-v] type mapname\n", progname); +#endif + exit(EX_USAGE); + + case T_UNKNOWN: + fprintf(stderr, "%s: Unknown database type %s\n", + progname, typename); + exit(EX_USAGE); + +#ifndef NDBM + case T_DBM: +#endif +#ifndef NEWDB + case T_BTREE: + case T_HASH: +#endif + fprintf(stderr, "%s: Type %s not supported in this version\n", + progname, typename); + exit(EX_UNAVAILABLE); + +#ifdef NEWDB + case T_BTREE: +# if DB_VERSION_MAJOR < 2 + bzero(&bti, sizeof bti); +# else + bzero(&dbinfo, sizeof dbinfo); +# endif + if (allowdups) + { +# if DB_VERSION_MAJOR < 2 + bti.flags |= R_DUP; +# else + dbinfo.flags |= DB_DUP; +# endif + } + if (allowdups || allowreplace) + putflags = 0; + else + { +# if DB_VERSION_MAJOR < 2 + putflags = R_NOOVERWRITE; +# else + putflags = DB_NOOVERWRITE; +# endif + } + break; + + case T_HASH: +# if DB_VERSION_MAJOR < 2 + bzero(&hinfo, sizeof hinfo); +# else + bzero(&dbinfo, sizeof dbinfo); +# endif + if (allowreplace) + putflags = 0; + else + { +# if DB_VERSION_MAJOR < 2 + putflags = R_NOOVERWRITE; +# else + putflags = DB_NOOVERWRITE; +# endif + } + break; +#endif +#ifdef NDBM + case T_DBM: + if (allowdups) + { + fprintf(stderr, "%s: Type %s does not support -d (allow dups)\n", + progname, typename); + exit(EX_UNAVAILABLE); + } + if (allowreplace) + putflags = DBM_REPLACE; + else + putflags = DBM_INSERT; + break; +#endif + } + + /* + ** Adjust file names. + */ + + if (ext != NULL) + { + int el, fl; + + el = strlen(ext); + fl = strlen(mapname); + if (el + fl + 1 >= sizeof fbuf) + { + fprintf(stderr, "%s: file name too long", mapname); + exit(EX_USAGE); + } + if (fl < el || strcmp(&mapname[fl - el], ext) != 0) + { + strcpy(fbuf, mapname); + strcat(fbuf, ext); + mapname = fbuf; + } + } + + if (!notrunc) + sff |= SFF_CREAT; + switch (type) + { +#ifdef NEWDB + case T_BTREE: + case T_HASH: + if (strlen(mapname) >= sizeof dbuf) + { + fprintf(stderr, + "%s: map name too long\n", mapname); + exit(EX_USAGE); + } + strcpy(dbuf, mapname); + if ((st = safefile(dbuf, RealUid, RealGid, RealUserName, + sff, S_IWUSR, &std)) != 0) + { + fprintf(stderr, + "%s: could not create: %s\n", + dbuf, errstring(st)); + exit(EX_CANTCREAT); + } + break; +#endif +#ifdef NDBM + case T_DBM: + if (strlen(mapname) + 5 > sizeof dbuf) + { + fprintf(stderr, + "%s: map name too long\n", mapname); + exit(EX_USAGE); + } + sprintf(dbuf, "%s.dir", mapname); + if ((st = safefile(dbuf, RealUid, RealGid, RealUserName, + sff, S_IWUSR, &std)) != 0) + { + fprintf(stderr, + "%s: could not create: %s\n", + dbuf, errstring(st)); + exit(EX_CANTCREAT); + } + sprintf(pbuf, "%s.pag", mapname); + if ((st = safefile(pbuf, RealUid, RealGid, RealUserName, + sff, S_IWUSR, &stp)) != 0) + { + fprintf(stderr, + "%s: could not create: %s\n", + pbuf, errstring(st)); + exit(EX_CANTCREAT); + } + break; +#endif + default: + fprintf(stderr, + "%s: internal error: type %d\n", + progname, + type); + exit(EX_SOFTWARE); + } + + /* + ** Create the database. + */ + + mode = O_RDWR; + if (!notrunc) + mode |= O_CREAT|O_TRUNC; +#if O_EXLOCK + mode |= O_EXLOCK; +#else + /* pre-lock the database */ + fd = safeopen(dbuf, mode & ~O_TRUNC, 0644, sff); + if (fd < 0) + { + fprintf(stderr, "%s: cannot create type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } +#endif + switch (type) + { +#ifdef NDBM + case T_DBM: + dbp.dbm = dbm_open(mapname, mode, 0644); + if (dbp.dbm != NULL && + dbm_dirfno(dbp.dbm) == dbm_pagfno(dbp.dbm)) + { + fprintf(stderr, "dbm map %s: cannot run with GDBM\n", + mapname); + dbm_close(dbp.dbm); + exit(EX_CONFIG); + } + if (dbp.dbm != NULL && + (filechanged(dbuf, dbm_dirfno(dbp.dbm), &std) || + filechanged(pbuf, dbm_pagfno(dbp.dbm), &stp))) + { + fprintf(stderr, + "dbm map %s: file changed after open\n", + mapname); + dbm_close(dbp.dbm); + exit(EX_CANTCREAT); + } +#if _FFR_TRUSTED_USER + if (geteuid() == 0 && TrustedUid != 0) + { + if (fchown(dbm_dirfno(dbp.dbm), TrustedUid, -1) < 0 || + fchown(dbm_pagfno(dbp.dbm), TrustedUid, -1) < 0) + { + fprintf(stderr, + "WARNING: ownership change on %s failed: %s", + mapname, errstring(errno)); + } + } +#endif + + break; +#endif + +#ifdef NEWDB + case T_HASH: + /* tweak some parameters for performance */ +# if DB_VERSION_MAJOR < 2 + hinfo.nelem = 4096; + hinfo.cachesize = dbcachesize; +# else + dbinfo.h_nelem = 4096; + dbinfo.db_cachesize = dbcachesize; +# endif + +# if DB_VERSION_MAJOR < 2 + dbp.db = dbopen(mapname, mode, 0644, DB_HASH, &hinfo); +# else + { + int flags = 0; + + if (bitset(O_CREAT, mode)) + flags |= DB_CREATE; + if (bitset(O_TRUNC, mode)) + flags |= DB_TRUNCATE; + + dbp.db = NULL; + errno = db_open(mapname, DB_HASH, flags, 0644, + NULL, &dbinfo, &dbp.db); + } +# endif + if (dbp.db != NULL) + { + int fd; + +# if DB_VERSION_MAJOR < 2 + fd = dbp.db->fd(dbp.db); +# else + fd = -1; + errno = dbp.db->fd(dbp.db, &fd); +# endif + if (filechanged(dbuf, fd, &std)) + { + fprintf(stderr, + "db map %s: file changed after open\n", + mapname); +# if DB_VERSION_MAJOR < 2 + dbp.db->close(dbp.db); +# else + errno = dbp.db->close(dbp.db, 0); +# endif + exit(EX_CANTCREAT); + } + (void) (*dbp.db->sync)(dbp.db, 0); +#if _FFR_TRUSTED_USER + if (geteuid() == 0 && TrustedUid != 0) + { + if (fchown(fd, TrustedUid, -1) < 0) + { + fprintf(stderr, + "WARNING: ownership change on %s failed: %s", + mapname, errstring(errno)); + } + } +#endif + } + break; + + case T_BTREE: + /* tweak some parameters for performance */ +# if DB_VERSION_MAJOR < 2 + bti.cachesize = dbcachesize; +# else + dbinfo.db_cachesize = dbcachesize; +# endif + +# if DB_VERSION_MAJOR < 2 + dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti); +# else + { + int flags = 0; + + if (bitset(O_CREAT, mode)) + flags |= DB_CREATE; + if (bitset(O_TRUNC, mode)) + flags |= DB_TRUNCATE; + + dbp.db = NULL; + errno = db_open(mapname, DB_BTREE, flags, 0644, + NULL, &dbinfo, &dbp.db); + } +# endif + if (dbp.db != NULL) + { + int fd; + +# if DB_VERSION_MAJOR < 2 + fd = dbp.db->fd(dbp.db); +# else + fd = -1; + errno = dbp.db->fd(dbp.db, &fd); +# endif + if (filechanged(dbuf, fd, &std)) + { + fprintf(stderr, + "db map %s: file changed after open\n", + mapname); +# if DB_VERSION_MAJOR < 2 + dbp.db->close(dbp.db); +# else + errno = dbp.db->close(dbp.db, 0); +# endif + exit(EX_CANTCREAT); + } + (void) (*dbp.db->sync)(dbp.db, 0); +#if _FFR_TRUSTED_USER + if (geteuid() == 0 && TrustedUid != 0) + { + if (fchown(fd, TrustedUid, -1) < 0) + { + fprintf(stderr, + "WARNING: ownership change on %s failed: %s", + mapname, errstring(errno)); + } + } +#endif + } + break; +#endif + + default: + fprintf(stderr, "%s: internal error: type %d\n", + progname, type); + exit(EX_SOFTWARE); + } + + if (dbp.dbx == NULL) + { + fprintf(stderr, "%s: cannot open type %s map %s\n", + progname, typename, mapname); + exit(EX_CANTCREAT); + } + + /* + ** Copy the data + */ + + lineno = 0; + exitstat = EX_OK; + while (fgets(ibuf, sizeof ibuf, stdin) != NULL) + { + register char *p; + + lineno++; + + /* + ** Parse the line. + */ + + p = strchr(ibuf, '\n'); + if (p != NULL) + *p = '\0'; + else if (!feof(stdin)) + { + fprintf(stderr, "%s: %s: line %d: line too long (%ld bytes max)\n", + progname, mapname, lineno, (long) sizeof ibuf); + continue; + } + + if (ibuf[0] == '\0' || ibuf[0] == '#') + continue; + if (isascii(ibuf[0]) && isspace(ibuf[0])) + { + fprintf(stderr, "%s: %s: line %d: syntax error (leading space)\n", + progname, mapname, lineno); + continue; + } +#ifdef NEWDB + if (type == T_HASH || type == T_BTREE) + { + bzero(&key.db, sizeof key.db); + bzero(&val.db, sizeof val.db); + } +#endif + + key.xx.data = ibuf; + for (p = ibuf; *p != '\0' && !(isascii(*p) && isspace(*p)); p++) + { + if (foldcase && isascii(*p) && isupper(*p)) + *p = tolower(*p); + } + key.xx.size = p - key.xx.data; + if (inclnull) + key.xx.size++; + if (*p != '\0') + *p++ = '\0'; + while (isascii(*p) && isspace(*p)) + p++; + if (*p == '\0') + { + fprintf(stderr, "%s: %s: line %d: no RHS for LHS %s\n", + progname, mapname, lineno, key.xx.data); + continue; + } + val.xx.data = p; + val.xx.size = strlen(p); + if (inclnull) + val.xx.size++; + + /* + ** Do the database insert. + */ + + if (verbose) + { + printf("key=`%s', val=`%s'\n", key.xx.data, val.xx.data); + } + + switch (type) + { +#ifdef NDBM + case T_DBM: + st = dbm_store(dbp.dbm, key.dbm, val.dbm, putflags); + break; +#endif + +#ifdef NEWDB + case T_BTREE: + case T_HASH: +# if DB_VERSION_MAJOR < 2 + st = (*dbp.db->put)(dbp.db, &key.db, &val.db, putflags); +# else + errno = (*dbp.db->put)(dbp.db, NULL, &key.db, + &val.db, putflags); + switch (errno) + { + case DB_KEYEXIST: + st = 1; + break; + + case 0: + st = 0; + break; + + default: + st = -1; + break; + } +# endif + break; +#endif + default: + break; + } + + if (st < 0) + { + fprintf(stderr, "%s: %s: line %d: key %s: put error\n", + progname, mapname, lineno, key.xx.data); + perror(mapname); + exitstat = EX_IOERR; + } + else if (st > 0) + { + fprintf(stderr, + "%s: %s: line %d: key %s: duplicate key\n", + progname, mapname, lineno, key.xx.data); + } + } + + /* + ** Now close the database. + */ + + switch (type) + { +#ifdef NDBM + case T_DBM: + dbm_close(dbp.dbm); + break; +#endif + +#ifdef NEWDB + case T_HASH: + case T_BTREE: +# if DB_VERSION_MAJOR < 2 + if ((*dbp.db->close)(dbp.db) < 0) +# else + if ((errno = (*dbp.db->close)(dbp.db, 0)) != 0) +# endif + { + fprintf(stderr, "%s: %s: error on close\n", + progname, mapname); + perror(mapname); + exitstat = EX_IOERR; + } +#endif + default: + break; + } + +#if !O_EXLOCK + /* release locks */ + close(fd); +#endif + + exit (exitstat); +} +/* +** LOCKFILE -- lock a file using flock or (shudder) fcntl locking +** +** Parameters: +** fd -- the file descriptor of the file. +** filename -- the file name (for error messages). +** ext -- the filename extension. +** type -- type of the lock. Bits can be: +** LOCK_EX -- exclusive lock. +** LOCK_NB -- non-blocking. +** +** Returns: +** TRUE if the lock was acquired. +** FALSE otherwise. +*/ + +bool +lockfile(fd, filename, ext, type) + int fd; + char *filename; + char *ext; + int type; +{ +# if !HASFLOCK + int action; + struct flock lfd; + extern int errno; + + bzero(&lfd, sizeof lfd); + if (bitset(LOCK_UN, type)) + lfd.l_type = F_UNLCK; + else if (bitset(LOCK_EX, type)) + lfd.l_type = F_WRLCK; + else + lfd.l_type = F_RDLCK; + if (bitset(LOCK_NB, type)) + action = F_SETLK; + else + action = F_SETLKW; + + if (fcntl(fd, action, &lfd) >= 0) + return TRUE; + + /* + ** On SunOS, if you are testing using -oQ/tmp/mqueue or + ** -oA/tmp/aliases or anything like that, and /tmp is mounted + ** as type "tmp" (that is, served from swap space), the + ** previous fcntl will fail with "Invalid argument" errors. + ** Since this is fairly common during testing, we will assume + ** that this indicates that the lock is successfully grabbed. + */ + + if (errno == EINVAL) + return TRUE; + +# else /* HASFLOCK */ + + if (flock(fd, type) >= 0) + return TRUE; + +# endif + + return FALSE; +} + +/*VARARGS1*/ +void +#ifdef __STDC__ +message(const char *msg, ...) +#else +message(msg, va_alist) + const char *msg; + va_dcl +#endif +{ + const char *m; + VA_LOCAL_DECL + + m = msg; + if (isascii(m[0]) && isdigit(m[0]) && + isascii(m[1]) && isdigit(m[1]) && + isascii(m[2]) && isdigit(m[2]) && m[3] == ' ') + m += 4; + VA_START(msg); + vfprintf(stderr, m, ap); + VA_END; + fprintf(stderr, "\n"); +} + +/*VARARGS1*/ +void +#ifdef __STDC__ +syserr(const char *msg, ...) +#else +syserr(msg, va_alist) + const char *msg; + va_dcl +#endif +{ + const char *m; + VA_LOCAL_DECL + + m = msg; + if (isascii(m[0]) && isdigit(m[0]) && + isascii(m[1]) && isdigit(m[1]) && + isascii(m[2]) && isdigit(m[2]) && m[3] == ' ') + m += 4; + VA_START(msg); + vfprintf(stderr, m, ap); + VA_END; + fprintf(stderr, "\n"); +} + +const char * +errstring(err) + int err; +{ +#if !HASSTRERROR + static char errstr[64]; +# if !defined(ERRLIST_PREDEFINED) + extern char *sys_errlist[]; + extern int sys_nerr; +# endif +#endif + + /* handle pseudo-errors internal to sendmail */ + switch (err) + { + case E_SM_OPENTIMEOUT: + return "Timeout on file open"; + + case E_SM_NOSLINK: + return "Symbolic links not allowed"; + + case E_SM_NOHLINK: + return "Hard links not allowed"; + + case E_SM_REGONLY: + return "Regular files only"; + + case E_SM_ISEXEC: + return "Executable files not allowed"; + + case E_SM_WWDIR: + return "World writable directory"; + + case E_SM_GWDIR: + return "Group writable directory"; + + case E_SM_FILECHANGE: + return "File changed after open"; + + case E_SM_WWFILE: + return "World writable file"; + + case E_SM_GWFILE: + return "Group writable file"; + } + +#if HASSTRERROR + return strerror(err); +#else + if (err < 0 || err >= sys_nerr) + { + sprintf(errstr, "Error %d", err); + return errstr; + } + return sys_errlist[err]; +#endif +} |
