From fd57f063dc5f6d87967fde28c2591998d3e7f05e Mon Sep 17 00:00:00 2001 From: Eric Allman Date: Tue, 13 Jul 1993 19:58:50 -0800 Subject: [PATCH] many fixes. primarily fix for seteuid problem in 8.2; also, Solaris compatibility fixes; timed out messages problems; messages silently discarded if checkcompat returned EX_TEMPFAIL SCCS-vsn: usr.sbin/sendmail/src/READ_ME 8.3 SCCS-vsn: usr.sbin/sendmail/src/usersmtp.c 8.4 SCCS-vsn: usr.sbin/sendmail/src/recipient.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/main.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/envelope.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/conf.h 8.3 SCCS-vsn: usr.sbin/sendmail/src/version.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/sendmail.h 8.3 SCCS-vsn: usr.sbin/sendmail/src/savemail.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/daemon.c 8.2 SCCS-vsn: usr.sbin/sendmail/src/srvrsmtp.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/clock.c 8.2 SCCS-vsn: usr.sbin/sendmail/src/util.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/readcf.c 8.2 SCCS-vsn: usr.sbin/sendmail/src/deliver.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/queue.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/conf.c 8.3 SCCS-vsn: usr.sbin/sendmail/src/alias.c 8.3 --- usr/src/usr.sbin/sendmail/src/READ_ME | 14 ++++- usr/src/usr.sbin/sendmail/src/alias.c | 23 ++++++-- usr/src/usr.sbin/sendmail/src/clock.c | 12 +++- usr/src/usr.sbin/sendmail/src/conf.c | 51 ++++++---------- usr/src/usr.sbin/sendmail/src/conf.h | 72 +++++++++++++++++------ usr/src/usr.sbin/sendmail/src/daemon.c | 18 +++++- usr/src/usr.sbin/sendmail/src/deliver.c | 6 +- usr/src/usr.sbin/sendmail/src/envelope.c | 20 +++++-- usr/src/usr.sbin/sendmail/src/main.c | 38 ++++++++---- usr/src/usr.sbin/sendmail/src/queue.c | 8 +-- usr/src/usr.sbin/sendmail/src/readcf.c | 2 +- usr/src/usr.sbin/sendmail/src/recipient.c | 8 +-- usr/src/usr.sbin/sendmail/src/savemail.c | 15 +++-- usr/src/usr.sbin/sendmail/src/sendmail.h | 5 +- usr/src/usr.sbin/sendmail/src/srvrsmtp.c | 24 ++++++-- usr/src/usr.sbin/sendmail/src/usersmtp.c | 13 ++-- usr/src/usr.sbin/sendmail/src/util.c | 7 ++- usr/src/usr.sbin/sendmail/src/version.c | 4 +- 18 files changed, 230 insertions(+), 110 deletions(-) diff --git a/usr/src/usr.sbin/sendmail/src/READ_ME b/usr/src/usr.sbin/sendmail/src/READ_ME index f80d571474..4f7d1d598a 100644 --- a/usr/src/usr.sbin/sendmail/src/READ_ME +++ b/usr/src/usr.sbin/sendmail/src/READ_ME @@ -4,7 +4,7 @@ # # %sccs.include.redist.sh% # -# @(#)READ_ME 8.2 (Berkeley) %G% +# @(#)READ_ME 8.3 (Berkeley) %G% # This directory contains the source files for sendmail. @@ -66,6 +66,16 @@ HASINITGROUPS Define this if you have the initgroups(3) routine. HASSETVBUF Define this if you have the setvbuf(3) library call. If you don't, setlinebuf will be used instead. This defaults on if your compiler defines __STDC__. +HASSETEUID Define this if you have seteuid(2) ***AND*** root can use + it to change to an arbitrary user. This second condition + is not satisfied on AIX 3.x. You may find that + your system has setreuid(2) or setresuid(2), in which + case you will also have to #define seteuid(uid) to be + the appropriate call. The important thing is that you + have a call that will set the effective uid and NOT + set the real or saved uid. Setting this improves the + security somewhat, since sendmail doesn't have to read + .forward and :include: files as root. LA_TYPE The type of load average your kernel supports. These can be LA_SUBR (4) if you have the getloadavg(3) routine, LA_FLOAT (3) if you read kmem and interpret the value @@ -204,4 +214,4 @@ version.c The version number and information about this Eric Allman -(Version 8.2, last update %G% 06:52:16) +(Version 8.3, last update %G% 12:58:13) diff --git a/usr/src/usr.sbin/sendmail/src/alias.c b/usr/src/usr.sbin/sendmail/src/alias.c index b53f8d59af..98952c6e62 100644 --- a/usr/src/usr.sbin/sendmail/src/alias.c +++ b/usr/src/usr.sbin/sendmail/src/alias.c @@ -11,7 +11,7 @@ # include #ifndef lint -static char sccsid[] = "@(#)alias.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) %G%"; #endif /* not lint */ @@ -670,7 +670,7 @@ forward(user, sendq, e) { char *pp; char *ep; -#ifdef _POSIX_SAVED_IDS +#ifdef HASSETEUID register ADDRESS *ca; uid_t saveduid, uid; #endif @@ -693,7 +693,7 @@ forward(user, sendq, e) if (ForwardPath == NULL) ForwardPath = newstr("\201z/.forward"); -#ifdef _POSIX_SAVED_IDS +#ifdef HASSETEUID ca = getctladdr(user); if (ca != NULL) uid = ca->q_uid; @@ -715,19 +715,30 @@ forward(user, sendq, e) if (tTd(27, 3)) printf("forward: trying %s\n", buf); -#ifdef _POSIX_SAVED_IDS + if (tTd(27, 9)) + printf("forward: old uid = %d/%d\n", getuid(), geteuid()); + +#ifdef HASSETEUID saveduid = geteuid(); if (saveduid == 0 && uid != 0) (void) seteuid(uid); #endif + if (tTd(27, 9)) + printf("forward: new uid = %d/%d\n", getuid(), geteuid()); + err = include(buf, TRUE, user, sendq, e); -#ifdef _POSIX_SAVED_IDS +#ifdef HASSETEUID if (saveduid == 0 && uid != 0) - (void) seteuid(saveduid); + if (seteuid(saveduid) < 0) + syserr("seteuid(%d) failure (real=%d, eff=%d)", + saveduid, getuid(), geteuid()); #endif + if (tTd(27, 9)) + printf("forward: reset uid = %d/%d\n", getuid(), geteuid()); + if (err == 0) break; if (transienterror(err)) diff --git a/usr/src/usr.sbin/sendmail/src/clock.c b/usr/src/usr.sbin/sendmail/src/clock.c index d111e9a5e4..d7d2f16872 100644 --- a/usr/src/usr.sbin/sendmail/src/clock.c +++ b/usr/src/usr.sbin/sendmail/src/clock.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)clock.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)clock.c 8.2 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -140,6 +140,9 @@ tick() register time_t now; register EVENT *ev; int mypid = getpid(); +#ifdef SIG_UNBLOCK + sigset_t ss; +#endif (void) signal(SIGALRM, SIG_IGN); (void) alarm(0); @@ -164,10 +167,17 @@ tick() /* we must be careful in here because ev_func may not return */ (void) signal(SIGALRM, tick); +#ifdef SIG_UNBLOCK + /* unblock SIGALRM signal */ + sigemptyset(&ss); + sigaddset(&ss, SIGALRM); + sigprocmask(SIG_UNBLOCK, &ss, NULL); +#else #ifdef SIGVTALRM /* reset 4.2bsd signal mask to allow future alarms */ (void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM)); #endif /* SIGVTALRM */ +#endif /* SIG_UNBLOCK */ f = ev->ev_func; arg = ev->ev_arg; diff --git a/usr/src/usr.sbin/sendmail/src/conf.c b/usr/src/usr.sbin/sendmail/src/conf.c index 0821b4e246..d0c3cecb8e 100644 --- a/usr/src/usr.sbin/sendmail/src/conf.c +++ b/usr/src/usr.sbin/sendmail/src/conf.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)conf.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)conf.c 8.3 (Berkeley) %G%"; #endif /* not lint */ # include @@ -162,7 +162,7 @@ setdefaults(e) WkClassFact = 1800L; /* option z */ WkTimeFact = 90000L; /* option Z */ QueueFactor = WkRecipFact * 20; /* option q */ - FileMode = (getuid() != geteuid()) ? 0644 : 0600; + FileMode = (RealUid != geteuid()) ? 0644 : 0600; /* option F */ DefUid = 1; /* option u */ DefGid = 1; /* option g */ @@ -325,30 +325,6 @@ setupmaps() #undef MAPDEF /* -** GETRUID -- get real user id (V7) -*/ - -getruid() -{ - if (OpMode == MD_DAEMON) - return (RealUid); - else - return (getuid()); -} - - -/* -** GETRGID -- get real group id (V7). -*/ - -getrgid() -{ - if (OpMode == MD_DAEMON) - return (RealGid); - else - return (getgid()); -} - /* ** USERNAME -- return the user id of the logged in user. ** ** Parameters: @@ -377,13 +353,13 @@ username() myname = getlogin(); if (myname == NULL || myname[0] == '\0') { - pw = getpwuid(getruid()); + pw = getpwuid(RealUid); if (pw != NULL) myname = newstr(pw->pw_name); } else { - uid_t uid = getuid(); + uid_t uid = RealUid; myname = newstr(myname); if ((pw = getpwnam(myname)) == NULL || @@ -997,19 +973,30 @@ unsetenv(name) ** none */ -#ifdef SYSTEM5 +#ifdef SOLARIS +# include +#endif int -getdtablesize() +getdtsize() { +#ifdef RLIMIT_NOFILE + struct rlimit rl; + + if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) + return rl.rlim_cur; +#endif + # ifdef _SC_OPEN_MAX return sysconf(_SC_OPEN_MAX); # else +# ifdef HASGETDTABLESIZE + return getdtablesize(); +# else return NOFILE; +# endif # endif } - -#endif /* ** UNAME -- get the UUCP name of this system. */ diff --git a/usr/src/usr.sbin/sendmail/src/conf.h b/usr/src/usr.sbin/sendmail/src/conf.h index 6d34c69641..ad5102c5f0 100644 --- a/usr/src/usr.sbin/sendmail/src/conf.h +++ b/usr/src/usr.sbin/sendmail/src/conf.h @@ -5,7 +5,7 @@ * * %sccs.include.redist.c% * - * @(#)conf.h 8.2 (Berkeley) %G% + * @(#)conf.h 8.3 (Berkeley) %G% */ /* @@ -66,16 +66,29 @@ ** change these. */ +/* general "standard C" defines */ #ifdef __STDC__ # define HASSETVBUF 1 /* yes, we have setvbuf in libc */ #endif +/* general POSIX defines */ +#ifdef _POSIX_VERSION +# define HASSETSID 1 /* has setsid(2) call */ +#endif + +/* +** Per-Operating System defines +*/ + /* HP-UX -- tested for 8.07 */ # ifdef __hpux -# define SYSTEM5 1 +# define SYSTEM5 1 /* include all the System V defines */ # define UNSETENV 1 /* need unsetenv(3) support */ -# define seteuid setuid -# define HASSETVBUF /* we have setvbuf in libc (but not __STDC__) */ +# define HASSETEUID 1 /* we have seteuid call */ +# define seteuid(uid) setresuid(-1, uid, -1) +# ifndef __STDC__ +# define HASSETVBUF 1 /* we have setvbuf in libc (but not __STDC__) */ +# endif # endif /* IBM AIX 3.x -- actually tested for 3.2.3 */ @@ -93,47 +106,70 @@ # define setpgrp BSDsetpgrp # endif -/* general System V defines */ -# ifdef SYSTEM5 -# define LOCKF 1 /* use System V lockf instead of flock */ -# define SYS5TZ 1 /* use System V style timezones */ -# define HASUNAME 1 /* use System V uname system call */ -# endif - +/* various systems from Sun Microsystems */ #if defined(sun) && !defined(BSD) + # define UNSETENV 1 /* need unsetenv(3) support */ # ifdef SOLARIS + /* Solaris 2.x */ # define LOCKF 1 /* use System V lockf instead of flock */ -# define UNSETENV 1 /* need unsetenv(3) support */ # define HASUSTAT 1 /* has the ustat(2) syscall */ +# define bcopy(s, d, l) (memmove((d), (s), (l))) +# define bzero(d, l) (memset((d), '\0', (l))) +# define bcmp(s, d, l) (memcmp((s), (d), (l))) +# include + # else + /* SunOS 4.1.x */ # define HASSTATFS 1 /* has the statfs(2) syscall */ +# define HASSETEUID 1 /* we have seteuid call */ # include -# endif +# endif #endif +/* Digital Ultrix 4.2A or 4.3 */ #ifdef ultrix # define HASSTATFS 1 /* has the statfs(2) syscall */ +# define HASSETEUID 1 /* we have seteuid call */ #endif -#ifdef _POSIX_VERSION -# define HASSETSID 1 /* has setsid(2) call */ +/* OSF/1 (tested on Alpha) */ +#ifdef __osf__ +# define HASSETEUID 1 /* we have seteuid call */ +# define seteuid(uid) setreuid(-1, uid) #endif +/* NeXTstep */ #ifdef __NeXT__ # define sleep sleepX # define UNSETENV 1 /* need unsetenv(3) support */ #endif +/* various flavors of BSD */ +#ifdef BSD +# define HASGETDTABLESIZE 1 /* we have getdtablesize(2) call */ +#endif + +/* 4.4BSD */ #ifdef BSD4_4 # include -# ifndef _POSIX_SAVED_IDS -# define _POSIX_SAVED_IDS /* safe because we actually use seteuid */ -# endif +# define HASSETEUID 1 /* we have seteuid(2) call */ #endif +/* +** End of Per-Operating System defines +*/ + +/* general System V defines */ +# ifdef SYSTEM5 +# define LOCKF 1 /* use System V lockf instead of flock */ +# define SYS5TZ 1 /* use System V style timezones */ +# define HASUNAME 1 /* use System V uname system call */ +# define NEEDGETDTABLESIZE 1 /* needs a replacement getdtablesize */ +# endif + /* ** Due to a "feature" in some operating systems such as Ultrix 4.3 and ** HPUX 8.0, if you receive a "No route to host" message (ICMP message diff --git a/usr/src/usr.sbin/sendmail/src/daemon.c b/usr/src/usr.sbin/sendmail/src/daemon.c index 30c4f5f919..df4fdda83b 100644 --- a/usr/src/usr.sbin/sendmail/src/daemon.c +++ b/usr/src/usr.sbin/sendmail/src/daemon.c @@ -13,9 +13,9 @@ #ifndef lint #ifdef DAEMON -static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) %G% (with daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.2 (Berkeley) %G% (with daemon mode)"; #else -static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) %G% (without daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.2 (Berkeley) %G% (without daemon mode)"; #endif #endif /* not lint */ @@ -108,7 +108,11 @@ getrequests() syserr("554 service \"smtp\" unknown"); goto severe; } +#ifdef _SCO_unix_ + DaemonAddr.sin.sin_port = htons(sp->s_port); +#else DaemonAddr.sin.sin_port = sp->s_port; +#endif } /* @@ -316,7 +320,11 @@ gothostent: syserr("554 makeconnection: service \"smtp\" unknown"); return (EX_OSERR); } +#ifdef _SCO_unix_ + port = htons(sp->s_port); +#else port = sp->s_port; +#endif } switch (addr.sa.sa_family) @@ -571,7 +579,13 @@ getauthinfo(fd) /* create foreign address */ sp = getservbyname("auth", "tcp"); if (sp != NULL) + { +#ifdef _SCO_unix_ + fa.sin.sin_port = htons(sp->s_port); +#else fa.sin.sin_port = sp->s_port; +#endif + } else fa.sin.sin_port = htons(113); diff --git a/usr/src/usr.sbin/sendmail/src/deliver.c b/usr/src/usr.sbin/sendmail/src/deliver.c index c182e2da89..6b76d8c346 100644 --- a/usr/src/usr.sbin/sendmail/src/deliver.c +++ b/usr/src/usr.sbin/sendmail/src/deliver.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)deliver.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)deliver.c 8.3 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -474,6 +474,9 @@ sendenvelope(e, mode) bitset(QDONTSEND, q->q_flags)) continue; + if (tTd(13, 3)) + printf("FATAL ERRORS\n"); + e->e_flags |= EF_FATALERRS; if (q->q_owner == NULL && strcmp(e->e_from.q_paddr, "<>") != 0) @@ -790,6 +793,7 @@ deliver(e, firstto) rcode = checkcompat(to, e); if (rcode != EX_OK) { + markfailure(e, to, rcode); giveresponse(rcode, m, NULL, e); continue; } diff --git a/usr/src/usr.sbin/sendmail/src/envelope.c b/usr/src/usr.sbin/sendmail/src/envelope.c index 32716bb217..45279fff15 100644 --- a/usr/src/usr.sbin/sendmail/src/envelope.c +++ b/usr/src/usr.sbin/sendmail/src/envelope.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)envelope.c 8.3 (Berkeley) %G%"; #endif /* not lint */ #include "sendmail.h" @@ -132,7 +132,14 @@ dropenvelope(e) message(buf); } e->e_flags |= EF_TIMEOUT|EF_CLRQUEUE; - fprintf(e->e_xfp, "421 Message timed out\n"); + fprintf(e->e_xfp, "Message could not be delivered for %s\n", + pintvl(TimeOuts.to_q_return, FALSE)); + fprintf(e->e_xfp, "Message will be deleted from queue\n"); + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QQUEUEUP, q->q_flags)) + q->q_flags |= QBADADDR; + } } else if (TimeOuts.to_q_warning > 0 && curtime() > e->e_ctime + TimeOuts.to_q_warning) @@ -155,6 +162,11 @@ dropenvelope(e) pintvl(TimeOuts.to_q_warning, FALSE)); fprintf(e->e_xfp, "Will keep trying until message is %s old\n", pintvl(TimeOuts.to_q_return, FALSE)); + for (q = e->e_sendqueue; q != NULL; q = q->q_next) + { + if (bitset(QQUEUEUP, q->q_flags)) + q->q_flags |= QREPORT; + } } /* @@ -625,8 +637,8 @@ setsender(from, e, delimptr, internal) { if (e->e_from.q_home == NULL) e->e_from.q_home = getenv("HOME"); - e->e_from.q_uid = getuid(); - e->e_from.q_gid = getgid(); + e->e_from.q_uid = RealUid; + e->e_from.q_gid = RealGid; } /* diff --git a/usr/src/usr.sbin/sendmail/src/main.c b/usr/src/usr.sbin/sendmail/src/main.c index 1df525b0e8..338cade2e3 100644 --- a/usr/src/usr.sbin/sendmail/src/main.c +++ b/usr/src/usr.sbin/sendmail/src/main.c @@ -13,7 +13,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)main.c 8.3 (Berkeley) %G%"; #endif /* not lint */ #define _DEFINE @@ -153,7 +153,7 @@ main(argc, argv, envp) #endif /* in 4.4BSD, the table can be huge; impose a reasonable limit */ - DtableSize = getdtablesize(); + DtableSize = getdtsize(); if (DtableSize > 256) DtableSize = 256; @@ -209,6 +209,9 @@ main(argc, argv, envp) else (void) sprintf(RealUserName, "Unknown UID %d", RealUid); + /* our real uid will have to be root -- we will trash this later */ + setuid((uid_t) 0); + /* Handle any non-getoptable constructions. */ obsolete(argv); @@ -236,8 +239,8 @@ main(argc, argv, envp) case 'C': ConfFile = optarg; - (void) setgid(getrgid()); - (void) setuid(getruid()); + (void) setgid(RealGid); + (void) setuid(RealUid); safecf = FALSE; nothaw = TRUE; break; @@ -390,7 +393,7 @@ main(argc, argv, envp) { case MD_DAEMON: # ifdef DAEMON - if (getuid() != 0) { + if (RealUid != 0) { usrerr("Permission denied"); exit (EX_USAGE); } @@ -436,7 +439,7 @@ main(argc, argv, envp) break; case 'C': /* select configuration file (already done) */ - if (getuid() != 0) + if (RealUid != 0) auth_warning(CurEnv, "Processed by %s with -C %s", RealUserName, optarg); @@ -529,7 +532,7 @@ main(argc, argv, envp) break; case 'X': /* traffic log file */ - setuid(getuid()); + setuid(RealUid); TrafficLogFile = fopen(optarg, "a"); if (TrafficLogFile == NULL) { @@ -609,14 +612,14 @@ main(argc, argv, envp) # ifdef QUEUE - if (queuemode && getuid() != 0) + if (queuemode && RealUid != 0) { struct stat stbuf; /* check to see if we own the queue directory */ if (stat(QueueDir, &stbuf) < 0) syserr("main: cannot stat %s", QueueDir); - if (stbuf.st_uid != getuid()) + if (stbuf.st_uid != RealUid) { /* nope, really a botch */ usrerr("Permission denied"); @@ -630,8 +633,8 @@ main(argc, argv, envp) # ifdef FROZENCONFIG case MD_FREEZE: /* this is critical to avoid forgeries of the frozen config */ - (void) setgid(getgid()); - (void) setuid(getuid()); + (void) setgid(RealGid); + (void) setuid(RealUid); /* freeze the configuration */ freeze(FreezeFile); @@ -709,7 +712,10 @@ main(argc, argv, envp) /* if we've had errors so far, exit now */ if (ExitStat != EX_OK && OpMode != MD_TEST) + { + setuid(RealUid); exit(ExitStat); + } /* ** Do operation-mode-dependent initialization. @@ -722,6 +728,7 @@ main(argc, argv, envp) #ifdef QUEUE dropenvelope(CurEnv); printqueue(); + setuid(RealUid); exit(EX_OK); #else /* QUEUE */ usrerr("No queue to print"); @@ -731,6 +738,7 @@ main(argc, argv, envp) case MD_INITALIAS: /* initialize alias database */ initmaps(TRUE, CurEnv); + setuid(RealUid); exit(EX_OK); case MD_DAEMON: @@ -1061,6 +1069,10 @@ finis() # endif /* LOG */ if (ExitStat == EX_TEMPFAIL) ExitStat = EX_OK; + + /* reset uid for process accounting */ + setuid(RealUid); + exit(ExitStat); } /* @@ -1087,6 +1099,10 @@ intsig() #ifdef XLA xla_all_end(); #endif + + /* reset uid for process accounting */ + setuid(RealUid); + exit(EX_OK); } /* diff --git a/usr/src/usr.sbin/sendmail/src/queue.c b/usr/src/usr.sbin/sendmail/src/queue.c index 3c8ae20e97..1a285cb58e 100644 --- a/usr/src/usr.sbin/sendmail/src/queue.c +++ b/usr/src/usr.sbin/sendmail/src/queue.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef QUEUE -static char sccsid[] = "@(#)queue.c 8.2 (Berkeley) %G% (with queueing)"; +static char sccsid[] = "@(#)queue.c 8.3 (Berkeley) %G% (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 8.2 (Berkeley) %G% (without queueing)"; +static char sccsid[] = "@(#)queue.c 8.3 (Berkeley) %G% (without queueing)"; #endif #endif /* not lint */ @@ -1099,7 +1099,7 @@ printqueue() ** Check for permission to print the queue */ - if (bitset(PRIV_RESTRMAILQ, PrivacyFlags) && getuid() != 0) + if (bitset(PRIV_RESTRMAILQ, PrivacyFlags) && RealUid != 0) { struct stat st; # ifdef NGROUPS @@ -1121,7 +1121,7 @@ printqueue() } if (n < 0) # else - if (getgid() != st.st_gid) + if (RealGid != st.st_gid) # endif { usrerr("510 You are not permitted to see the queue"); diff --git a/usr/src/usr.sbin/sendmail/src/readcf.c b/usr/src/usr.sbin/sendmail/src/readcf.c index 004a348c33..d4c559bbf0 100644 --- a/usr/src/usr.sbin/sendmail/src/readcf.c +++ b/usr/src/usr.sbin/sendmail/src/readcf.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)readcf.c 8.1 (Berkeley) %G%"; +static char sccsid[] = "@(#)readcf.c 8.2 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" diff --git a/usr/src/usr.sbin/sendmail/src/recipient.c b/usr/src/usr.sbin/sendmail/src/recipient.c index e1fcfae601..8c64238ff3 100644 --- a/usr/src/usr.sbin/sendmail/src/recipient.c +++ b/usr/src/usr.sbin/sendmail/src/recipient.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)recipient.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)recipient.c 8.3 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -352,7 +352,7 @@ recipient(a, sendq, e) usrerr("550 Cannot mail directly to files"); } else if ((stat(buf, &stb) >= 0) ? (!writable(&stb)) : - (*p = '\0', safefile(buf, getruid(), TRUE, S_IWRITE|S_IEXEC) != 0)) + (*p = '\0', safefile(buf, RealUid, TRUE, S_IWRITE|S_IEXEC) != 0)) { a->q_flags |= QBADADDR; giveresponse(EX_CANTCREAT, m, NULL, e); @@ -589,8 +589,8 @@ writable(s) if (bitset(0111, s->st_mode)) return (FALSE); - euid = getruid(); - egid = getrgid(); + euid = RealUid; + egid = RealGid; if (geteuid() == 0) { if (bitset(S_ISUID, s->st_mode)) diff --git a/usr/src/usr.sbin/sendmail/src/savemail.c b/usr/src/usr.sbin/sendmail/src/savemail.c index 777348a2e6..894ee2990b 100644 --- a/usr/src/usr.sbin/sendmail/src/savemail.c +++ b/usr/src/usr.sbin/sendmail/src/savemail.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)savemail.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)savemail.c 8.3 (Berkeley) %G%"; #endif /* not lint */ # include @@ -586,18 +586,23 @@ errbody(fp, m, e) printheader = TRUE; for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) { - if (bitset(QBADADDR, q->q_flags)) + if (bitset(QBADADDR|QREPORT, q->q_flags)) { if (printheader) { - putline(" ----- The following addresses failed -----", + putline(" ----- The following addresses had delivery problems -----", fp, m); printheader = FALSE; } if (q->q_alias != NULL) - putline(q->q_alias->q_paddr, fp, m); + strcpy(buf, q->q_alias->q_paddr); + else + strcpy(buf, q->q_paddr); + if (bitset(QBADADDR, q->q_flags)) + strcat(buf, " (hard error -- address deleted)"); else - putline(q->q_paddr, fp, m); + strcat(buf, " (temporary failure -- will retry)"); + putline(buf, fp, m); } } if (!printheader) diff --git a/usr/src/usr.sbin/sendmail/src/sendmail.h b/usr/src/usr.sbin/sendmail/src/sendmail.h index 278fadb696..ca9f3ced79 100644 --- a/usr/src/usr.sbin/sendmail/src/sendmail.h +++ b/usr/src/usr.sbin/sendmail/src/sendmail.h @@ -5,7 +5,7 @@ * * %sccs.include.redist.c% * - * @(#)sendmail.h 8.2 (Berkeley) %G% + * @(#)sendmail.h 8.3 (Berkeley) %G% */ /* @@ -15,7 +15,7 @@ # ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailSccsId[] = "@(#)sendmail.h 8.2 %G%"; +static char SmailSccsId[] = "@(#)sendmail.h 8.3 %G%"; # endif # else /* _DEFINE */ # define EXTERN extern @@ -133,6 +133,7 @@ typedef struct address ADDRESS; # define QNOTREMOTE 000100 /* not an address for remote forwarding */ # define QSELFREF 000200 /* this address references itself */ # define QVERIFIED 000400 /* verified, but not expanded */ +# define QREPORT 001000 /* report this address in return message */ # define QPSEUDO 000040 /* only on the list for verification */ /* ** Mailer definition structure. diff --git a/usr/src/usr.sbin/sendmail/src/srvrsmtp.c b/usr/src/usr.sbin/sendmail/src/srvrsmtp.c index fd88e06e89..76937abad9 100644 --- a/usr/src/usr.sbin/sendmail/src/srvrsmtp.c +++ b/usr/src/usr.sbin/sendmail/src/srvrsmtp.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)srvrsmtp.c 8.2 (Berkeley) %G% (with SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.3 (Berkeley) %G% (with SMTP)"; #else -static char sccsid[] = "@(#)srvrsmtp.c 8.2 (Berkeley) %G% (without SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.3 (Berkeley) %G% (without SMTP)"; #endif #endif /* not lint */ @@ -279,6 +279,7 @@ smtp(e) { QuickAbort = FALSE; SuprErrs = TRUE; + e->e_flags &= ~EF_FATALERRS; finis(); } break; @@ -444,15 +445,26 @@ smtp(e) } /* check to see if we need to re-expand aliases */ + /* also reset QBADADDR on already-diagnosted addrs */ + doublequeue = FALSE; for (a = e->e_sendqueue; a != NULL; a = a->q_next) { if (bitset(QVERIFIED, a->q_flags)) - break; + { + /* need to re-expand aliases */ + doublequeue = TRUE; + } + if (bitset(QBADADDR, a->q_flags)) + { + /* make this "go away" */ + a->q_flags |= QDONTSEND; + a->q_flags &= ~QBADADDR; + } } /* collect the text of the message */ SmtpPhase = "collect"; - collect(TRUE, a != NULL, e); + collect(TRUE, doublequeue, e); e->e_flags &= ~EF_FATALERRS; if (Errors != 0) goto abortmessage; @@ -476,7 +488,7 @@ smtp(e) */ SmtpPhase = "delivery"; - if (nrcpts != 1 && a == NULL) + if (nrcpts != 1 && !doublequeue) { HoldErrs = TRUE; e->e_errormode = EM_MAIL; @@ -510,7 +522,7 @@ smtp(e) e->e_errormode = EM_MAIL; /* if we just queued, poke it */ - if (a != NULL && e->e_sendmode != SM_QUEUE) + if (doublequeue && e->e_sendmode != SM_QUEUE) { unlockqueue(e); dowork(id, TRUE, TRUE, e); diff --git a/usr/src/usr.sbin/sendmail/src/usersmtp.c b/usr/src/usr.sbin/sendmail/src/usersmtp.c index 3b865375f8..912ddda64e 100644 --- a/usr/src/usr.sbin/sendmail/src/usersmtp.c +++ b/usr/src/usr.sbin/sendmail/src/usersmtp.c @@ -10,9 +10,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)usersmtp.c 8.3 (Berkeley) %G% (with SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.4 (Berkeley) %G% (with SMTP)"; #else -static char sccsid[] = "@(#)usersmtp.c 8.3 (Berkeley) %G% (without SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.4 (Berkeley) %G% (without SMTP)"; #endif #endif /* not lint */ @@ -434,7 +434,6 @@ smtpdata(m, mci, e) register int r; register EVENT *ev; time_t timeout; - time_t mintimeout; static int datatimeout(); /* @@ -489,10 +488,10 @@ smtpdata(m, mci, e) return EX_TEMPFAIL; } - timeout = e->e_msgsize / 64; - mintimeout = e->e_nrcpts * 90 + 60; - if (timeout < mintimeout) - timeout = mintimeout; + timeout = e->e_msgsize / 16; + if (timeout < (time_t) 60) + timeout = (time_t) 60; + timeout += e->e_nrcpts * 90; ev = setevent(timeout, datatimeout, 0); /* now output the actual message */ diff --git a/usr/src/usr.sbin/sendmail/src/util.c b/usr/src/usr.sbin/sendmail/src/util.c index 0afa640b5d..028bbbf273 100644 --- a/usr/src/usr.sbin/sendmail/src/util.c +++ b/usr/src/usr.sbin/sendmail/src/util.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)util.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)util.c 8.3 (Berkeley) %G%"; #endif /* not lint */ # include "sendmail.h" @@ -550,7 +550,10 @@ dfopen(filename, omode, cmode) (void) lockfile(fd, filename, locktype); errno = 0; } - return fdopen(fd, om->farg); + if (fd < 0) + return NULL; + else + return fdopen(fd, om->farg); } /* ** PUTLINE -- put a line like fputs obeying SMTP conventions diff --git a/usr/src/usr.sbin/sendmail/src/version.c b/usr/src/usr.sbin/sendmail/src/version.c index 69bfc6d0dc..0098730f9c 100644 --- a/usr/src/usr.sbin/sendmail/src/version.c +++ b/usr/src/usr.sbin/sendmail/src/version.c @@ -7,7 +7,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)version.c 8.2 (Berkeley) %G%"; +static char sccsid[] = "@(#)version.c 8.3 (Berkeley) %G%"; #endif /* not lint */ -char Version[] = "8.2"; +char Version[] = "8.3"; -- 2.20.1