diff options
Diffstat (limited to 'usr.sbin/sendmail/src')
| -rw-r--r-- | usr.sbin/sendmail/src/READ_ME | 29 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/TRACEFLAGS | 3 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/envelope.c | 4 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/err.c | 32 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/map.c | 330 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/mci.c | 10 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/queue.c | 24 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/safefile.c | 32 | ||||
| -rw-r--r-- | usr.sbin/sendmail/src/version.c | 4 |
9 files changed, 368 insertions, 100 deletions
diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME index 8046d41ac299..154916a0a6e6 100644 --- a/usr.sbin/sendmail/src/READ_ME +++ b/usr.sbin/sendmail/src/READ_ME @@ -30,7 +30,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)READ_ME 8.142 (Berkeley) 6/3/97 +# @(#)READ_ME 8.148 (Berkeley) 8/1/97 # This directory contains the source files for sendmail. @@ -149,7 +149,7 @@ The options are: NEWDB The new Berkeley DB package. Some systems (e.g., BSD/OS and Digital UNIX 4.0) have this package pre-installed. If your system does not have NEWDB installed, get the latest version - from FTP://ftp.sleepycat.com/db/packages/db.1.85.tar.gz. + from http://www.sleepycat.com/packages/db.1.85.tar.gz. DO NOT use the version from the Net2 distribution. If you are still running BSD/386 1.x, you will also need to define OLD_NEWDB. @@ -295,6 +295,8 @@ HASULIMIT Define this if you have the ulimit(2) syscall (System V HASWAITPID Define this if you have the waitpid(2) syscall. HASGETDTABLESIZE Define this if you have the getdtablesize(2) syscall. +HAS_ST_GEN Define this to 1 if your system has the st_gen field in + the stat structure (see stat(2)). USESTRERROR Define this if you have the libc strerror function (which should be declared in <errno.h>), and it should be used instead of sys_errlist. @@ -339,6 +341,12 @@ SLEEP_T The type returned by the system sleep() function. ARBPTR_T The type of an arbitrary pointer -- defaults to "void *". If you are an very old compiler you may need to define this to be "char *". +SOCKADDR_LEN_T The type used for the third parameter to accept(2), + getsockname(2), and getpeername(2), representing the + length of a struct sockaddr. Defaults to int. +SOCKOPT_LEN_T The type used for the fifth parameter to getsockopt(2) + and setsockopt(2), representing the length of the option + buffer. Defaults to int. LA_TYPE The type of load average your kernel supports. These can be one of: LA_ZERO (1) -- it always returns the load average as @@ -457,6 +465,14 @@ SAFENFSPATHCONF Set this to 1 if and only if you have verified that a assumption! The test/t_pathconf.c program will try this for you -- you have to run it in a directory that is mounted from a server that allows file giveaway. +SIOCGIFCONF_IS_BROKEN + Set this if your system has an SIOCGIFCONF ioctl defined, + but it doesn't behave the same way as "most" systems (BSD, + Solaris, SunOS, HP-UX, etc.) +SIOCGIFNUM_IS_BROKEN + Set this if your system has an SIOCGIFNUM ioctl defined, + but it doesn't behave the same way as "most" systems + (Solaris, HP-UX). @@ -633,6 +649,12 @@ GCC 2.7.x problems problems. I recommend against using -O on that architecture. This has been seen on FreeBSD 2.0.5 RELEASE. +GDBM GDBM does not work with sendmail 8.8 because the additional + security checks and file locking cause problems. Unfortunately, + gdbm does not provide a compile flag in its version of ndbm.h so + the code can adapt. We expect this to be fixed in 8.9, but + probably at the cost of a new command line compile flag. + Configuration file location Up to 8.6, sendmail tried to find the sendmail.cf file in the same place as the vendors had put it, even when this was obviously @@ -960,6 +982,7 @@ A/UX then re-compile sendmail with "-lgdbm", "-DNDBM", and using the ndbm.h header file that comes with the gnu-package. This makes things behave properly. + [NOTE: see comment above about GDBM] I suppose porting the New Berkeley db package is another route, however, I made a quick attempt at it, and found it difficult @@ -1416,4 +1439,4 @@ version.c The version number and information about this Eric Allman -(Version 8.142, last update 6/3/97 11:34:09) +(Version 8.148, last update 8/1/97 16:41:54) diff --git a/usr.sbin/sendmail/src/TRACEFLAGS b/usr.sbin/sendmail/src/TRACEFLAGS index e9d4818356fd..db461db60fc4 100644 --- a/usr.sbin/sendmail/src/TRACEFLAGS +++ b/usr.sbin/sendmail/src/TRACEFLAGS @@ -55,6 +55,9 @@ 44 safefile.c safefile, safedirpath, filechanged 45 envelope.c setsender 46 envelope.c openxscript +47 main.c drop_privileges +48 parseaddr.c rscheck +48 conf.c validate_connection 49 conf.c checkcompat 50 envelope.c dropenvelope 51 queue.c unlockqueue diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c index 4dc07ae7fc33..3e0fc204020d 100644 --- a/usr.sbin/sendmail/src/envelope.c +++ b/usr.sbin/sendmail/src/envelope.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 8.104 (Berkeley) 6/3/97"; +static char sccsid[] = "@(#)envelope.c 8.105 (Berkeley) 6/24/97"; #endif /* not lint */ #include "sendmail.h" @@ -178,7 +178,7 @@ dropenvelope(e, fulldrop) { failure_return = TRUE; if (q->q_owner == NULL && !emptyaddr(&e->e_from)) - (void) sendtolist(e->e_from.q_paddr, NULL, + (void) sendtolist(e->e_from.q_paddr, NULLADDR, &e->e_errorqueue, 0, e); } else if (bitset(QPINGONSUCCESS, q->q_flags) && diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c index 5bec0884d02a..f4f95e6cd0f2 100644 --- a/usr.sbin/sendmail/src/err.c +++ b/usr.sbin/sendmail/src/err.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)err.c 8.62 (Berkeley) 6/5/97"; +static char sccsid[] = "@(#)err.c 8.64 (Berkeley) 7/25/97"; #endif /* not lint */ # include "sendmail.h" @@ -112,7 +112,7 @@ syserr(fmt, va_alist) puterrmsg(MsgBuf); /* save this message for mailq printing */ - if (!panic) + if (!panic && CurEnv != NULL) { if (CurEnv->e_message != NULL) free(CurEnv->e_message); @@ -140,9 +140,10 @@ syserr(fmt, va_alist) } if (LogLevel > 0) - sm_syslog(panic ? LOG_ALERT : LOG_CRIT, CurEnv->e_id, - "SYSERR(%s): %.900s", - uname, &MsgBuf[4]); + sm_syslog(panic ? LOG_ALERT : LOG_CRIT, + CurEnv == NULL ? NOQID : CurEnv->e_id, + "SYSERR(%s): %.900s", + uname, &MsgBuf[4]); switch (olderrno) { case EBADF: @@ -178,7 +179,7 @@ syserr(fmt, va_alist) exit(EX_OSERR); } errno = 0; - if (QuickAbort || (OnlyOneError && !HoldErrs)) + if (QuickAbort) longjmp(TopFrame, 2); } /* @@ -254,7 +255,7 @@ usrerr(fmt, va_alist) "%.900s", &MsgBuf[4]); - if (QuickAbort || (OnlyOneError && !HoldErrs)) + if (QuickAbort) longjmp(TopFrame, 1); } /* @@ -397,7 +398,8 @@ putoutmsg(msg, holdmsg, heldmsg) msg[0] = '4'; /* output to transcript if serious */ - if (!heldmsg && CurEnv->e_xfp != NULL && strchr("45", msg[0]) != NULL) + if (!heldmsg && CurEnv != NULL && CurEnv->e_xfp != NULL && + strchr("45", msg[0]) != NULL) fprintf(CurEnv->e_xfp, "%s\n", msg); if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) @@ -421,6 +423,9 @@ putoutmsg(msg, holdmsg, heldmsg) (void) fflush(stdout); + if (OutChannel == NULL) + return; + /* if DisConnected, OutChannel now points to the transcript */ if (!DisConnected && (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP)) @@ -441,7 +446,8 @@ putoutmsg(msg, holdmsg, heldmsg) ** rude servers don't read result. */ - if (feof(InChannel) || ferror(InChannel) || strncmp(msg, "221", 3) == 0) + if (InChannel == NULL || feof(InChannel) || ferror(InChannel) || + strncmp(msg, "221", 3) == 0) return; /* can't call syserr, 'cause we are using MsgBuf */ @@ -474,8 +480,16 @@ puterrmsg(msg) /* output the message as usual */ putoutmsg(msg, HoldErrs, FALSE); + /* be careful about multiple error messages */ + if (OnlyOneError) + HoldErrs = TRUE; + /* signal the error */ Errors++; + + if (CurEnv == NULL) + return; + if (msgcode == '6') { /* notify the postmaster */ diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c index e0a0fd240884..88e82b19f98a 100644 --- a/usr.sbin/sendmail/src/map.c +++ b/usr.sbin/sendmail/src/map.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)map.c 8.168 (Berkeley) 6/14/97"; +static char sccsid[] = "@(#)map.c 8.181 (Berkeley) 7/9/97"; #endif /* not lint */ #include "sendmail.h" @@ -113,14 +113,6 @@ extern bool extract_canonname __P((char *, char *, char[], int)); # define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */ #endif -#ifndef O_LEAVELOCKED -# if O_SHLOCK -# define O_LEAVELOCKED O_SHLOCK -# else -# define O_LEAVELOCKED 0x1000 -# endif -#endif - #ifndef O_ACCMODE # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) #endif @@ -733,7 +725,7 @@ extract_canonname(name, line, cbuf, cbuflen) #ifdef NDBM /* -** DBM_MAP_OPEN -- DBM-style map open +** NDBM_MAP_OPEN -- DBM-style map open */ bool @@ -743,7 +735,8 @@ ndbm_map_open(map, mode) { register DBM *dbm; struct stat st; - int fd; + int dfd; + int pfd; int sff; int ret; int smode = S_IREAD; @@ -760,10 +753,10 @@ ndbm_map_open(map, mode) /* do initial file and directory checks */ snprintf(dirfile, sizeof dirfile, "%s.dir", map->map_file); snprintf(pagfile, sizeof pagfile, "%s.pag", map->map_file); - sff = SFF_ROOTOK|SFF_REGONLY|SFF_CREAT; + sff = SFF_ROOTOK|SFF_REGONLY; if (mode == O_RDWR) { - sff |= SFF_NOLINK; + sff |= SFF_NOLINK|SFF_CREAT; smode = S_IWRITE; } else @@ -786,13 +779,21 @@ ndbm_map_open(map, mode) return FALSE; } if (std.st_mode == ST_MODE_NOFILE) - mode |= O_EXCL; + mode |= O_CREAT|O_EXCL; + + /* heuristic: if files are linked, this is actually gdbm */ + if (std.st_dev == stp.st_dev && std.st_ino == stp.st_ino) + { + syserr("dbm map \"%s\": cannot support GDBM", + map->map_mname); + return FALSE; + } #if LOCK_ON_OPEN if (mode == O_RDONLY) mode |= O_SHLOCK; else - mode |= O_CREAT|O_TRUNC|O_EXLOCK; + mode |= O_TRUNC|O_EXLOCK; #else if ((mode & O_ACCMODE) == O_RDWR) { @@ -804,7 +805,7 @@ ndbm_map_open(map, mode) ** but there isn't anything we can do about it. */ - mode |= O_CREAT|O_TRUNC; + mode |= O_TRUNC; # else /* ** This ugly code opens the map without truncating it, @@ -815,29 +816,57 @@ ndbm_map_open(map, mode) int dirfd; int pagfd; - dirfd = safeopen(dirfile, mode|O_CREAT, DBMMODE, + dirfd = safeopen(dirfile, mode, DBMMODE, SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT); - pagfd = safeopen(pagfile, mode|O_CREAT, DBMMODE, + pagfd = safeopen(pagfile, mode, DBMMODE, SFF_NOLINK|SFF_CREAT|SFF_OPENASROOT); if (dirfd < 0 || pagfd < 0) { + int save_errno = errno; + + if (dirfd >= 0) + (void) close(dirfd); + if (pagfd >= 0) + (void) close(pagfd); + errno = save_errno; syserr("ndbm_map_open: cannot create database %s", map->map_file); - close(dirfd); - close(pagfd); return FALSE; } - if (ftruncate(dirfd, (off_t) 0) < 0) - syserr("ndbm_map_open: cannot truncate %s.dir", + if (ftruncate(dirfd, (off_t) 0) < 0 || + ftruncate(pagfd, (off_t) 0) < 0) + { + int save_errno = errno; + + (void) close(dirfd); + (void) close(pagfd); + errno = save_errno; + syserr("ndbm_map_open: cannot truncate %s.{dir,pag}", map->map_file); - if (ftruncate(pagfd, (off_t) 0) < 0) - syserr("ndbm_map_open: cannot truncate %s.pag", + return FALSE; + } + + /* if new file, get "before" bits for later filechanged check */ + if (std.st_mode == ST_MODE_NOFILE && + (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0)) + { + int save_errno = errno; + + (void) close(dirfd); + (void) close(pagfd); + errno = save_errno; + syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file", map->map_file); + return FALSE; + } /* have to save the lock for the duration (bletch) */ map->map_lockfd = dirfd; close(pagfd); + + /* twiddle bits for dbm_open */ + mode &= ~(O_CREAT|O_EXCL); # endif } #endif @@ -846,37 +875,46 @@ ndbm_map_open(map, mode) dbm = dbm_open(map->map_file, mode, DBMMODE); if (dbm == NULL) { + int save_errno = errno; + if (bitset(MF_ALIAS, map->map_mflags) && aliaswait(map, ".pag", FALSE)) return TRUE; - if (!bitset(MF_OPTIONAL, map->map_mflags)) - syserr("Cannot open DBM database %s", map->map_file); #if !LOCK_ON_OPEN && !NOFTRUNCATE if (map->map_lockfd >= 0) close(map->map_lockfd); #endif + errno = save_errno; + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("Cannot open DBM database %s", map->map_file); return FALSE; } - if (filechanged(dirfile, dbm_dirfno(dbm), &std, sff) || - filechanged(pagfile, dbm_pagfno(dbm), &stp, sff)) + dfd = dbm_dirfno(dbm); + pfd = dbm_pagfno(dbm); + if (filechanged(dirfile, dfd, &std, sff) || + filechanged(pagfile, pfd, &stp, sff)) { - syserr("ndbm_map_open(%s): file changed after open", - map->map_file); + int save_errno = errno; + dbm_close(dbm); #if !LOCK_ON_OPEN && !NOFTRUNCATE if (map->map_lockfd >= 0) close(map->map_lockfd); #endif + errno = save_errno; + syserr("ndbm_map_open(%s): file changed after open", + map->map_file); return FALSE; } - map->map_db1 = (void *) dbm; - fd = dbm_dirfno((DBM *) map->map_db1); + map->map_db1 = (ARBPTR_T) dbm; if (mode == O_RDONLY) { #if LOCK_ON_OPEN - if (fd >= 0) - (void) lockfile(fd, map->map_file, ".pag", LOCK_UN); + if (dfd >= 0) + (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN); + if (pfd >= 0) + (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN); #endif if (bitset(MF_ALIAS, map->map_mflags) && !aliaswait(map, ".pag", TRUE)) @@ -886,14 +924,14 @@ ndbm_map_open(map, mode) { map->map_mflags |= MF_LOCKED; } - if (fstat(dbm_dirfno((DBM *) map->map_db1), &st) >= 0) + if (fstat(dfd, &st) >= 0) map->map_mtime = st.st_mtime; return TRUE; } /* -** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map +** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map */ char * @@ -951,7 +989,7 @@ ndbm_map_lookup(map, name, av, statp) /* -** DBM_MAP_STORE -- store a datum in the database +** NDBM_MAP_STORE -- store a datum in the database */ void @@ -994,7 +1032,7 @@ ndbm_map_store(map, lhs, rhs) if (stat > 0) { if (!bitset(MF_APPEND, map->map_mflags)) - usrerr("050 Warning: duplicate alias name %s", lhs); + message("050 Warning: duplicate alias name %s", lhs); else { static char *buf = NULL; @@ -1157,7 +1195,6 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) int fd; int sff; int saveerrno; - bool leavelocked = bitset(O_LEAVELOCKED, mode); struct stat st; char buf[MAXNAME + 1]; @@ -1170,10 +1207,10 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) mode &= O_ACCMODE; omode = mode; - sff = SFF_ROOTOK|SFF_REGONLY|SFF_CREAT; + sff = SFF_ROOTOK|SFF_REGONLY; if (mode == O_RDWR) { - sff |= SFF_NOLINK; + sff |= SFF_NOLINK|SFF_CREAT; smode = S_IWRITE; } else @@ -1187,28 +1224,26 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) { /* cannot open this map */ if (tTd(38, 2)) - printf("\tunsafe map file: %d\n", i); + printf("\tunsafe map file: %s\n", errstring(i)); + errno = i; if (!bitset(MF_OPTIONAL, map->map_mflags)) syserr("%s map \"%s\": unsafe map file %s", mapclassname, map->map_mname, map->map_file); return FALSE; } if (st.st_mode == ST_MODE_NOFILE) - omode |= O_EXCL; + omode |= O_CREAT|O_EXCL; map->map_lockfd = -1; #if LOCK_ON_OPEN if (mode == O_RDWR) - omode |= O_CREAT|O_TRUNC|O_EXLOCK; + omode |= O_TRUNC|O_EXLOCK; # if !OLD_NEWDB else omode |= O_SHLOCK; # endif #else - if (mode == O_RDWR) - omode |= O_CREAT; - /* ** Pre-lock the file to avoid race conditions. In particular, ** since dbopen returns NULL if the file is zero length, we @@ -1216,26 +1251,51 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) */ fd = open(buf, omode, DBMMODE); - if (fd < 0) { if (!bitset(MF_OPTIONAL, map->map_mflags)) syserr("db_map_open: cannot pre-open database %s", buf); - close(fd); return FALSE; } - if (!lockfile(fd, map->map_file, ".db", - mode == O_RDONLY ? LOCK_SH : LOCK_EX)) + + /* make sure no baddies slipped in just before the open... */ + if (filechanged(buf, fd, &st, sff)) + { + int save_errno = errno; + + (void) close(fd); + errno = save_errno; + syserr("db_map_open(%s): file changed after pre-open", buf); + return FALSE; + } + + /* if new file, get the "before" bits for later filechanged check */ + if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0) + { + int save_errno = errno; + + (void) close(fd); + errno = save_errno; + syserr("db_map_open(%s): cannot fstat pre-opened file", + buf); + return FALSE; + } + + /* actually lock the pre-opened file */ + if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX)) syserr("db_map_open: cannot lock %s", buf); + + /* set up mode bits for dbopen */ if (mode == O_RDWR) omode |= O_TRUNC; + omode &= ~(O_EXCL|O_CREAT); #endif db = dbopen(buf, omode, DBMMODE, dbtype, openinfo); saveerrno = errno; #if !LOCK_ON_OPEN - if (leavelocked || mode == O_RDWR) + if (mode == O_RDWR) map->map_lockfd = fd; else (void) close(fd); @@ -1246,25 +1306,28 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && aliaswait(map, ".db", FALSE)) return TRUE; - errno = saveerrno; - if (!bitset(MF_OPTIONAL, map->map_mflags)) - syserr("Cannot open %s database %s", - mapclassname, map->map_file); #if !LOCK_ON_OPEN if (map->map_lockfd >= 0) (void) close(map->map_lockfd); #endif + errno = saveerrno; + if (!bitset(MF_OPTIONAL, map->map_mflags)) + syserr("Cannot open %s database %s", + mapclassname, map->map_file); return FALSE; } if (filechanged(buf, db->fd(db), &st, sff)) { - syserr("db_map_open(%s): file changed after open", buf); + int save_errno = errno; + db->close(db); #if !LOCK_ON_OPEN if (map->map_lockfd >= 0) close(map->map_lockfd); #endif + errno = save_errno; + syserr("db_map_open(%s): file changed after open", buf); return FALSE; } @@ -1273,9 +1336,9 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) #if !OLD_NEWDB fd = db->fd(db); # if LOCK_ON_OPEN - if (fd >= 0 && mode == O_RDONLY && !leavelocked) + if (fd >= 0 && mode == O_RDONLY) { - (void) lockfile(fd, map->map_file, ".db", LOCK_UN); + (void) lockfile(fd, buf, NULL, LOCK_UN); } # endif #endif @@ -1291,7 +1354,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo) map->map_mtime = st.st_mtime; #endif - map->map_db2 = (void *) db; + map->map_db2 = (ARBPTR_T) db; if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && !aliaswait(map, ".db", TRUE)) return FALSE; @@ -1312,16 +1375,26 @@ db_map_lookup(map, name, av, statp) { DBT key, val; register DB *db = (DB *) map->map_db2; + int i; int st; int saveerrno; int fd; struct stat stbuf; char keybuf[MAXNAME + 1]; + char buf[MAXNAME + 1]; if (tTd(38, 20)) printf("db_map_lookup(%s, %s)\n", map->map_mname, name); + i = strlen(map->map_file); + if (i > MAXNAME) + i = MAXNAME; + strncpy(buf, map->map_file, i); + buf[i] = '\0'; + if (i > 3 && strcmp(&buf[i - 3], ".db") == 0) + buf[i - 3] = '\0'; + key.size = strlen(name); if (key.size > sizeof keybuf - 1) key.size = sizeof keybuf - 1; @@ -1331,9 +1404,10 @@ db_map_lookup(map, name, av, statp) if (!bitset(MF_NOFOLDCASE, map->map_mflags)) makelower(keybuf); #if !OLD_NEWDB + lockdb: fd = db->fd(db); if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) - (void) lockfile(fd, map->map_file, ".db", LOCK_SH); + (void) lockfile(fd, buf, ".db", LOCK_SH); if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime) { /* Reopen the database to sync the cache */ @@ -1342,14 +1416,13 @@ db_map_lookup(map, name, av, statp) map->map_class->map_close(map); map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); - omode |= O_LEAVELOCKED; if (map->map_class->map_open(map, omode)) { map->map_mflags |= MF_OPEN; if ((omode && O_ACCMODE) == O_RDWR) map->map_mflags |= MF_WRITABLE; db = (DB *) map->map_db2; - fd = db->fd(db); + goto lockdb; } else { @@ -1385,7 +1458,7 @@ db_map_lookup(map, name, av, statp) saveerrno = errno; #if !OLD_NEWDB if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) - (void) lockfile(fd, map->map_file, ".db", LOCK_UN); + (void) lockfile(fd, buf, ".db", LOCK_UN); #endif if (st != 0) { @@ -1446,7 +1519,7 @@ db_map_store(map, lhs, rhs) if (stat > 0) { if (!bitset(MF_APPEND, map->map_mflags)) - usrerr("050 Warning: duplicate alias name %s", lhs); + message("050 Warning: duplicate alias name %s", lhs); else { static char *buf = NULL; @@ -1500,13 +1573,19 @@ db_map_close(map) db_map_store(map, "@", "@"); } - if (db->close(db) != 0) - syserr("readaliases: db close failure"); +#if OLD_NEWDB + (void) db->sync(db); +#else + (void) db->sync(db, 0); +#endif #if !LOCK_ON_OPEN if (map->map_lockfd >= 0) (void) close(map->map_lockfd); #endif + + if (db->close(db) != 0) + syserr("readaliases: db close failure"); } #endif @@ -2735,6 +2814,123 @@ ldap_map_parseargs(map,args) #endif /* LDAP Modules */ /* +** syslog map +*/ + +#if _FFR_SYSLOG_MAP + +#define map_prio map_lockfd /* overload field */ + +/* +** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages. +*/ + +bool +syslog_map_parseargs(map, args) + MAP *map; + char *args; +{ + char *p = args; + char *priority = NULL; + + for (;;) + { + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '-') + break; + if (*++p == 'L') + priority = ++p; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if (*p != '\0') + *p++ = '\0'; + } + + if (priority == NULL) + map->map_prio = LOG_INFO; + else + { + if (strncasecmp("LOG_", priority, 4) == 0) + priority += 4; + +#ifdef LOG_EMERG + if (strcasecmp("EMERG", priority) == 0) + map->map_prio = LOG_EMERG; + else +#endif +#ifdef LOG_ALERT + if (strcasecmp("ALERT", priority) == 0) + map->map_prio = LOG_ALERT; + else +#endif +#ifdef LOG_CRIT + if (strcasecmp("CRIT", priority) == 0) + map->map_prio = LOG_CRIT; + else +#endif +#ifdef LOG_ERR + if (strcasecmp("ERR", priority) == 0) + map->map_prio = LOG_ERR; + else +#endif +#ifdef LOG_WARNING + if (strcasecmp("WARNING", priority) == 0) + map->map_prio = LOG_WARNING; + else +#endif +#ifdef LOG_NOTICE + if (strcasecmp("NOTICE", priority) == 0) + map->map_prio = LOG_NOTICE; + else +#endif +#ifdef LOG_INFO + if (strcasecmp("INFO", priority) == 0) + map->map_prio = LOG_INFO; + else +#endif +#ifdef LOG_DEBUG + if (strcasecmp("DEBUG", priority) == 0) + map->map_prio = LOG_DEBUG; + else +#endif + { + syserr("syslog_map_parseargs: Unknown priority %s\n", + priority); + return FALSE; + } + } + return TRUE; +} + +/* +** SYSLOG_MAP_LOOKUP -- rewrite and syslog message. Always return empty string +*/ + +char * +syslog_map_lookup(map, string, args, statp) + MAP *map; + char *string; + char **args; + int *statp; +{ + char *ptr = map_rewrite(map, string, strlen(string), args); + + if (ptr != NULL) + { + if (tTd(38, 20)) + printf("syslog_map_lookup(%s (priority %d): %s\n", + map->map_mname, map->map_prio, ptr); + + sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr); + } + + *statp = EX_OK; + return ""; +} + +#endif /* _FFR_SYSLOG_MAP */ +/* ** HESIOD Modules */ diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c index f8ba789ff8a0..929d82d463a3 100644 --- a/usr.sbin/sendmail/src/mci.c +++ b/usr.sbin/sendmail/src/mci.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mci.c 8.62 (Berkeley) 5/29/97"; +static char sccsid[] = "@(#)mci.c 8.66 (Berkeley) 8/2/97"; #endif /* not lint */ #include "sendmail.h" @@ -330,10 +330,10 @@ mci_get(host, m) { /* get peer host address for logging reasons only */ /* (this should really be in the mci struct) */ - int socksize = sizeof CurHostAddr; + SOCKADDR_LEN_T socklen = sizeof CurHostAddr; (void) getpeername(fileno(mci->mci_in), - (struct sockaddr *) &CurHostAddr, &socksize); + (struct sockaddr *) &CurHostAddr, &socklen); } # endif } @@ -571,7 +571,7 @@ mci_lock_host_statfile(mci) goto cleanup; } - mci->mci_statfile = safefopen(fname, O_RDWR|O_CREAT, FileMode, + mci->mci_statfile = safefopen(fname, O_RDWR, FileMode, SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY|SFF_CREAT); if (mci->mci_statfile == NULL) @@ -694,7 +694,7 @@ mci_load_persistent(mci) } fp = safefopen(fname, O_RDONLY, FileMode, - SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY); + SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY); if (fp == NULL) { /* I can't think of any reason this should ever happen */ diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c index 13965de01be2..1d812b8f50d6 100644 --- a/usr.sbin/sendmail/src/queue.c +++ b/usr.sbin/sendmail/src/queue.c @@ -36,9 +36,9 @@ #ifndef lint #if QUEUE -static char sccsid[] = "@(#)queue.c 8.169 (Berkeley) 6/14/97 (with queueing)"; +static char sccsid[] = "@(#)queue.c 8.174 (Berkeley) 7/23/97 (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 8.169 (Berkeley) 6/14/97 (without queueing)"; +static char sccsid[] = "@(#)queue.c 8.174 (Berkeley) 7/23/97 (without queueing)"; #endif #endif /* not lint */ @@ -431,7 +431,9 @@ queueup(e, announce) fprintf(tfp, ".\n"); - if (fflush(tfp) < 0 || fsync(fileno(tfp)) < 0 || ferror(tfp)) + if (fflush(tfp) < 0 || + (SuperSafe && fsync(fileno(tfp)) < 0) || + ferror(tfp)) { if (newid) syserr("!552 Error writing control file %s", tf); @@ -553,7 +555,6 @@ runqueue(forkflag, verbose) extern ENVELOPE BlankEnvelope; extern void clrdaemon __P((void)); extern void runqueueevent __P((void)); - extern void drop_privileges __P((void)); DoQueueRun = FALSE; @@ -670,7 +671,7 @@ runqueue(forkflag, verbose) /* drop privileges */ if (geteuid() == (uid_t) 0) - drop_privileges(); + (void) drop_privileges(FALSE); /* ** Create ourselves an envelope @@ -684,7 +685,7 @@ runqueue(forkflag, verbose) if (forkflag) { disconnect(1, e); - OnlyOneError = QuickAbort = FALSE; + QuickAbort = FALSE; } /* @@ -1463,6 +1464,7 @@ dowork(id, forkflag, requeueflag, e) { if (tTd(40, 4)) printf("readqf(%s) failed\n", e->e_id); + e->e_id = NULL; if (forkflag) exit(EX_OK); else @@ -2325,13 +2327,17 @@ loseqfile(e, why) char *why; { char *p; - char buf[MAXQFNAME]; + char buf[MAXQFNAME + 1]; if (e == NULL || e->e_id == NULL) return; - if (strlen(e->e_id) > (SIZE_T) sizeof buf - 4) + p = queuename(e, 'q'); + if (strlen(p) > MAXQFNAME) + { + syserr("loseqfile: queuename (%s) too long", p); return; - strcpy(buf, queuename(e, 'q')); + } + strcpy(buf, p); p = queuename(e, 'Q'); if (rename(buf, p) < 0) syserr("cannot rename(%s, %s), uid=%d", buf, p, geteuid()); diff --git a/usr.sbin/sendmail/src/safefile.c b/usr.sbin/sendmail/src/safefile.c index 08660347cafe..842a09f8ca86 100644 --- a/usr.sbin/sendmail/src/safefile.c +++ b/usr.sbin/sendmail/src/safefile.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)safefile.c 8.12 (Berkeley) 6/14/97"; +static char sccsid[] = "@(#)safefile.c 8.18 (Berkeley) 8/1/97"; #endif /* not lint */ # include "sendmail.h" @@ -108,6 +108,10 @@ safefile(fn, uid, gid, uname, flags, mode, st) strcpy(fbuf, fn); fn = fbuf; + /* ignore SFF_SAFEDIRPATH if we are debugging */ + if (RealUid != 0 && RunAsUid == RealUid) + flags &= ~SFF_SAFEDIRPATH; + /* first check to see if the file exists at all */ #ifdef HASLSTAT if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st) @@ -464,6 +468,7 @@ safeopen(fn, omode, cmode, sff) if (bitset(O_CREAT, omode)) sff |= SFF_CREAT; + omode &= ~O_CREAT; smode = 0; switch (omode & O_ACCMODE) { @@ -494,8 +499,8 @@ safeopen(fn, omode, cmode, sff) errno = rval; return -1; } - if (stb.st_mode == ST_MODE_NOFILE) - omode |= O_EXCL; + if (stb.st_mode == ST_MODE_NOFILE && bitset(SFF_CREAT, sff)) + omode |= O_EXCL|O_CREAT; fd = dfopen(fn, omode, cmode, sff); if (fd < 0) @@ -561,10 +566,24 @@ safefopen(fn, omode, cmode, sff) } fd = safeopen(fn, omode, cmode, sff); if (fd < 0) + { + if (tTd(44, 10)) + printf("safefopen: safeopen failed: %s\n", + errstring(errno)); return NULL; + } fp = fdopen(fd, fmode); if (fp != NULL) return fp; + + if (tTd(44, 10)) + { + printf("safefopen: fdopen(%s, %s) failed: omode=%x, sff=%x, err=%s\n", + fn, fmode, omode, sff, errstring(errno)); +#ifndef NOT_SENDMAIL + dumpfd(fd, TRUE, FALSE); +#endif + } (void) close(fd); return NULL; } @@ -607,6 +626,9 @@ filechanged(fn, fd, stb, sff) if (sta.st_nlink != stb->st_nlink || sta.st_dev != stb->st_dev || sta.st_ino != stb->st_ino || +#if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */ + sta.st_gen != stb->st_gen || +#endif sta.st_uid != stb->st_uid || sta.st_gid != stb->st_gid) { @@ -619,6 +641,10 @@ filechanged(fn, fd, stb, sff) (long) stb->st_dev, (long) sta.st_dev); printf(" ino = %ld/%ld\n", (long) stb->st_ino, (long) sta.st_ino); +#if HAS_ST_GEN + printf(" gen = %ld/%ld\n", + (long) stb->st_gen, (long) sta.st_gen); +#endif printf(" uid = %ld/%ld\n", (long) stb->st_uid, (long) sta.st_uid); printf(" gid = %ld/%ld\n", diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c index 6f6ffad0c8ea..c531c5bdf075 100644 --- a/usr.sbin/sendmail/src/version.c +++ b/usr.sbin/sendmail/src/version.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)version.c 8.8.6.1 (Berkeley) 6/14/97"; +static char sccsid[] = "@(#)version.c 8.8.7.3 (Berkeley) 8/3/97"; #endif /* not lint */ -char Version[] = "8.8.6"; +char Version[] = "8.8.7"; |
