summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/src/parseaddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/parseaddr.c')
-rw-r--r--usr.sbin/sendmail/src/parseaddr.c427
1 files changed, 267 insertions, 160 deletions
diff --git a/usr.sbin/sendmail/src/parseaddr.c b/usr.sbin/sendmail/src/parseaddr.c
index 8951cac01cff..800a1372cdcd 100644
--- a/usr.sbin/sendmail/src/parseaddr.c
+++ b/usr.sbin/sendmail/src/parseaddr.c
@@ -33,7 +33,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)parseaddr.c 8.3 (Berkeley) 7/11/93";
+static char sccsid[] = "@(#)parseaddr.c 8.30 (Berkeley) 2/9/94";
#endif /* not lint */
# include "sendmail.h"
@@ -56,14 +56,8 @@ static char sccsid[] = "@(#)parseaddr.c 8.3 (Berkeley) 7/11/93";
** addr -- the address to parse.
** a -- a pointer to the address descriptor buffer.
** If NULL, a header will be created.
-** copyf -- determines what shall be copied:
-** -1 -- don't copy anything. The printname
-** (q_paddr) is just addr, and the
-** user & host are allocated internally
-** to parse.
-** 0 -- copy out the parsed user & host, but
-** don't copy the printname.
-** +1 -- copy everything.
+** flags -- describe detail for parsing. See RF_ definitions
+** in sendmail.h.
** delim -- the character to terminate the address, passed
** to prescan.
** delimptr -- if non-NULL, set to the location of the
@@ -83,10 +77,10 @@ static char sccsid[] = "@(#)parseaddr.c 8.3 (Berkeley) 7/11/93";
# define DELIMCHARS "()<>,;\r\n" /* default word delimiters */
ADDRESS *
-parseaddr(addr, a, copyf, delim, delimptr, e)
+parseaddr(addr, a, flags, delim, delimptr, e)
char *addr;
register ADDRESS *a;
- int copyf;
+ int flags;
int delim;
char **delimptr;
register ENVELOPE *e;
@@ -106,17 +100,10 @@ parseaddr(addr, a, copyf, delim, delimptr, e)
if (tTd(20, 1))
printf("\n--parseaddr(%s)\n", addr);
- if (invalidaddr(addr))
- {
- if (tTd(20, 1))
- printf("parseaddr-->bad address\n");
- return NULL;
- }
-
if (delimptr == NULL)
delimptr = &delimptrbuf;
- pvp = prescan(addr, delim, pvpbuf, delimptr);
+ pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr);
if (pvp == NULL)
{
if (tTd(20, 1))
@@ -124,42 +111,58 @@ parseaddr(addr, a, copyf, delim, delimptr, e)
return (NULL);
}
+ if (invalidaddr(addr, delim == '\0' ? NULL : *delimptr))
+ {
+ if (tTd(20, 1))
+ printf("parseaddr-->bad address\n");
+ return NULL;
+ }
+
+ /*
+ ** Save addr if we are going to have to.
+ **
+ ** We have to do this early because there is a chance that
+ ** the map lookups in the rewriting rules could clobber
+ ** static memory somewhere.
+ */
+
+ if (bitset(RF_COPYPADDR, flags) && addr != NULL)
+ {
+ char savec = **delimptr;
+
+ if (savec != '\0')
+ **delimptr = '\0';
+ addr = newstr(addr);
+ if (savec != '\0')
+ **delimptr = savec;
+ }
+
/*
** Apply rewriting rules.
** Ruleset 0 does basic parsing. It must resolve.
*/
queueup = FALSE;
- if (rewrite(pvp, 3, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
queueup = TRUE;
- if (rewrite(pvp, 0, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 0, 0, e) == EX_TEMPFAIL)
queueup = TRUE;
- /*
- ** See if we resolved to a real mailer.
- */
-
- if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
- {
- setstat(EX_USAGE);
- syserr("554 cannot resolve name %s", addr);
- return (NULL);
- }
/*
** Build canonical address from pvp.
*/
- a = buildaddr(pvp, a, e);
- if (a == NULL)
- return (NULL);
+ a = buildaddr(pvp, a, flags, e);
/*
** Make local copies of the host & user and then
** transport them out.
*/
- allocaddr(a, copyf, addr, *delimptr);
+ allocaddr(a, flags, addr);
+ if (bitset(QBADADDR, a->q_flags))
+ return a;
/*
** If there was a parsing failure, mark it for queueing.
@@ -201,18 +204,43 @@ parseaddr(addr, a, copyf, delim, delimptr, e)
*/
bool
-invalidaddr(addr)
+invalidaddr(addr, delimptr)
register char *addr;
+ char *delimptr;
{
+ char savedelim;
+
+ if (delimptr != NULL)
+ {
+ savedelim = *delimptr;
+ if (savedelim != '\0')
+ *delimptr = '\0';
+ }
+#if 0
+ /* for testing.... */
+ if (strcmp(addr, "INvalidADDR") == 0)
+ {
+ usrerr("553 INvalid ADDRess");
+ goto addrfailure;
+ }
+#endif
for (; *addr != '\0'; addr++)
{
- if ((*addr & 0340) != 0200)
- continue;
- setstat(EX_USAGE);
- usrerr("553 Address contained invalid control characters");
- return TRUE;
+ if ((*addr & 0340) == 0200)
+ break;
}
- return FALSE;
+ if (*addr == '\0')
+ {
+ if (savedelim != '\0' && delimptr != NULL)
+ *delimptr = savedelim;
+ return FALSE;
+ }
+ setstat(EX_USAGE);
+ usrerr("553 Address contained invalid control characters");
+ addrfailure:
+ if (savedelim != '\0' && delimptr != NULL)
+ *delimptr = savedelim;
+ return TRUE;
}
/*
** ALLOCADDR -- do local allocations of address on demand.
@@ -221,9 +249,9 @@ invalidaddr(addr)
**
** Parameters:
** a -- the address to reallocate.
-** copyf -- the copy flag (see parseaddr for description).
+** flags -- the copy flag (see RF_ definitions in sendmail.h
+** for a description).
** paddr -- the printname of the address.
-** delimptr -- a pointer to the address delimiter. Must be set.
**
** Returns:
** none.
@@ -232,34 +260,22 @@ invalidaddr(addr)
** Copies portions of a into local buffers as requested.
*/
-allocaddr(a, copyf, paddr, delimptr)
+allocaddr(a, flags, paddr)
register ADDRESS *a;
- int copyf;
+ int flags;
char *paddr;
- char *delimptr;
{
if (tTd(24, 4))
- printf("allocaddr(copyf=%d, paddr=%s)\n", copyf, paddr);
+ printf("allocaddr(flags=%o, paddr=%s)\n", flags, paddr);
- if (copyf > 0 && paddr != NULL)
- {
- char savec = *delimptr;
-
- if (savec != '\0')
- *delimptr = '\0';
- a->q_paddr = newstr(paddr);
- if (savec != '\0')
- *delimptr = savec;
- }
- else
- a->q_paddr = paddr;
+ a->q_paddr = paddr;
if (a->q_user == NULL)
a->q_user = "";
if (a->q_host == NULL)
a->q_host = "";
- if (copyf >= 0)
+ if (bitset(RF_COPYPARSE, flags))
{
a->q_host = newstr(a->q_host);
if (a->q_user != a->q_paddr)
@@ -292,6 +308,7 @@ allocaddr(a, copyf, paddr, delimptr)
** If '\t' then we are reading the .cf file.
** pvpbuf -- place to put the saved text -- note that
** the pointers are static.
+** pvpbsize -- size of pvpbuf.
** delimptr -- if non-NULL, set to the location of the
** terminating delimiter.
**
@@ -325,10 +342,34 @@ static short StateTab[NSTATES][NSTATES] =
/*ONE*/ OPR, OPR, OPR, OPR, OPR,
};
+/* token type table -- it gets modified with $o characters */
+static TokTypeTab[256] =
+{
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM,ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
+ OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+};
+
+#define toktype(c) ((int) TokTypeTab[(c) & 0xff])
+
+
# define NOCHAR -1 /* signal nothing in lookahead token */
char **
-prescan(addr, delim, pvpbuf, delimptr)
+prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
char *addr;
char delim;
char pvpbuf[];
@@ -346,8 +387,24 @@ prescan(addr, delim, pvpbuf, delimptr)
int newstate;
char *saveto = CurEnv->e_to;
static char *av[MAXATOM+1];
+ static char firsttime = TRUE;
extern int errno;
+ if (firsttime)
+ {
+ /* initialize the token type table */
+ char obuf[50];
+
+ firsttime = FALSE;
+ expand("\201o", obuf, &obuf[sizeof obuf - sizeof DELIMCHARS], CurEnv);
+ strcat(obuf, DELIMCHARS);
+ for (p = obuf; *p != '\0'; p++)
+ {
+ if (TokTypeTab[*p & 0xff] == ATM)
+ TokTypeTab[*p & 0xff] = OPR;
+ }
+ }
+
/* make sure error messages don't have garbage on them */
errno = 0;
@@ -377,9 +434,10 @@ prescan(addr, delim, pvpbuf, delimptr)
if (c != NOCHAR && !bslashmode)
{
/* see if there is room */
- if (q >= &pvpbuf[PSBUFSIZE - 5])
+ if (q >= &pvpbuf[pvpbsize - 5])
{
usrerr("553 Address too long");
+ returnnull:
if (delimptr != NULL)
*delimptr = p;
CurEnv->e_to = saveto;
@@ -397,18 +455,18 @@ prescan(addr, delim, pvpbuf, delimptr)
/* diagnose and patch up bad syntax */
if (state == QST)
{
- usrerr("553 Unbalanced '\"'");
+ usrerr("653 Unbalanced '\"'");
c = '"';
}
else if (cmntcnt > 0)
{
- usrerr("553 Unbalanced '('");
+ usrerr("653 Unbalanced '('");
c = ')';
}
else if (anglecnt > 0)
{
c = '>';
- usrerr("553 Unbalanced '<'");
+ usrerr("653 Unbalanced '<'");
}
else
break;
@@ -458,11 +516,8 @@ prescan(addr, delim, pvpbuf, delimptr)
{
if (cmntcnt <= 0)
{
- usrerr("553 Unbalanced ')'");
- if (delimptr != NULL)
- *delimptr = p;
- CurEnv->e_to = saveto;
- return (NULL);
+ usrerr("653 Unbalanced ')'");
+ c = NOCHAR;
}
else
cmntcnt--;
@@ -475,13 +530,11 @@ prescan(addr, delim, pvpbuf, delimptr)
{
if (anglecnt <= 0)
{
- usrerr("553 Unbalanced '>'");
- if (delimptr != NULL)
- *delimptr = p;
- CurEnv->e_to = saveto;
- return (NULL);
+ usrerr("653 Unbalanced '>'");
+ c = NOCHAR;
}
- anglecnt--;
+ else
+ anglecnt--;
}
else if (delim == ' ' && isascii(c) && isspace(c))
c = ' ';
@@ -516,10 +569,12 @@ prescan(addr, delim, pvpbuf, delimptr)
if (avp >= &av[MAXATOM])
{
syserr("553 prescan: too many tokens");
- if (delimptr != NULL)
- *delimptr = p;
- CurEnv->e_to = saveto;
- return (NULL);
+ goto returnnull;
+ }
+ if (q - tok > MAXNAME)
+ {
+ syserr("553 prescan: token too long");
+ goto returnnull;
}
*avp++ = tok;
}
@@ -535,50 +590,12 @@ prescan(addr, delim, pvpbuf, delimptr)
}
CurEnv->e_to = saveto;
if (av[0] == NULL)
- return (NULL);
- return (av);
-}
- /*
-** TOKTYPE -- return token type
-**
-** Parameters:
-** c -- the character in question.
-**
-** Returns:
-** Its type.
-**
-** Side Effects:
-** none.
-*/
-
-toktype(c)
- register int c;
-{
- static char buf[50];
- static bool firstime = TRUE;
-
- if (firstime)
{
- firstime = FALSE;
- expand("\201o", buf, &buf[sizeof buf - 1], CurEnv);
- (void) strcat(buf, DELIMCHARS);
+ if (tTd(22, 1))
+ printf("prescan: null leading token\n");
+ return (NULL);
}
- c &= 0377;
- if (c == MATCHCLASS || c == MATCHREPL || c == MATCHNCLASS)
- return (ONE);
- if (c == MACRODEXPAND)
- return (ONE);
- if (c == '"')
- return (QST);
- if ((c & 0340) == 0200)
- return (OPR);
- if (!isascii(c))
- return (ATM);
- if (isspace(c) || c == ')')
- return (SPC);
- if (strchr(buf, c) != NULL)
- return (OPR);
- return (ATM);
+ return (av);
}
/*
** REWRITE -- apply rewrite rules to token vector.
@@ -605,6 +622,7 @@ toktype(c)
** Parameters:
** pvp -- pointer to token vector.
** ruleset -- the ruleset to use for rewriting.
+** reclevel -- recursion level (to catch loops).
** e -- the current envelope.
**
** Returns:
@@ -624,11 +642,16 @@ struct match
# define MAXMATCH 9 /* max params per rewrite */
+# ifndef MAXRULERECURSION
+# define MAXRULERECURSION 50 /* max recursion depth */
+# endif
+
int
-rewrite(pvp, ruleset, e)
+rewrite(pvp, ruleset, reclevel, e)
char **pvp;
int ruleset;
+ int reclevel;
register ENVELOPE *e;
{
register char *ap; /* address pointer */
@@ -639,6 +662,7 @@ rewrite(pvp, ruleset, e)
register struct rewrite *rwr; /* pointer to current rewrite rule */
int ruleno; /* current rule number */
int rstat = EX_OK; /* return status */
+ int loopcount;
struct match mlist[MAXMATCH]; /* stores match on LHS */
char *npvp[MAXATOM+1]; /* temporary space for rebuild */
@@ -652,6 +676,11 @@ rewrite(pvp, ruleset, e)
syserr("554 rewrite: illegal ruleset number %d", ruleset);
return EX_CONFIG;
}
+ if (reclevel++ > MAXRULERECURSION)
+ {
+ syserr("rewrite: infinite recursion, ruleset %d", ruleset);
+ return EX_CONFIG;
+ }
if (pvp == NULL)
return EX_USAGE;
@@ -661,10 +690,9 @@ rewrite(pvp, ruleset, e)
*/
ruleno = 1;
+ loopcount = 0;
for (rwr = RewriteRules[ruleset]; rwr != NULL; )
{
- int loopcount = 0;
-
if (tTd(21, 12))
{
printf("-----trying rule:");
@@ -874,6 +902,7 @@ rewrite(pvp, ruleset, e)
printf("----- rule fails\n");
rwr = rwr->r_next;
ruleno++;
+ loopcount = 0;
continue;
}
@@ -890,6 +919,7 @@ rewrite(pvp, ruleset, e)
rvp++;
rwr = rwr->r_next;
ruleno++;
+ loopcount = 0;
}
else if ((*rp & 0377) == CANONHOST)
{
@@ -984,6 +1014,7 @@ rewrite(pvp, ruleset, e)
char *pvpb1[MAXATOM + 1];
char *argvect[10];
char pvpbuf[PSBUFSIZE];
+ char *nullpvp[1];
if ((**rvp & 0377) != HOSTBEGIN &&
(**rvp & 0377) != LOOKUPBEGIN)
@@ -1101,10 +1132,17 @@ rewrite(pvp, ruleset, e)
{
xpvp = key_rvp;
}
+ else if (*replac == '\0')
+ {
+ /* null replacement */
+ nullpvp[0] = NULL;
+ xpvp = nullpvp;
+ }
else
{
/* scan the new replacement */
- xpvp = prescan(replac, '\0', pvpbuf, NULL);
+ xpvp = prescan(replac, '\0', pvpbuf,
+ sizeof pvpbuf, NULL);
if (xpvp == NULL)
{
/* prescan already printed error */
@@ -1136,15 +1174,24 @@ rewrite(pvp, ruleset, e)
{
int stat;
- bcopy((char *) &npvp[2], (char *) pvp,
- (int) (avp - npvp - 2) * sizeof *avp);
- if (tTd(21, 3))
- printf("-----callsubr %s\n", npvp[1]);
- stat = rewrite(pvp, atoi(npvp[1]), e);
- if (rstat == EX_OK || stat == EX_TEMPFAIL)
- rstat = stat;
- if ((**pvp & 0377) == CANONNET)
+ if (npvp[1] == NULL)
+ {
+ syserr("parseaddr: NULL subroutine call in ruleset %d, rule %d",
+ ruleset, ruleno);
+ *pvp = NULL;
+ }
+ else
+ {
+ bcopy((char *) &npvp[2], (char *) pvp,
+ (int) (avp - npvp - 2) * sizeof *avp);
+ if (tTd(21, 3))
+ printf("-----callsubr %s\n", npvp[1]);
+ stat = rewrite(pvp, atoi(npvp[1]), reclevel, e);
+ if (rstat == EX_OK || stat == EX_TEMPFAIL)
+ rstat = stat;
+ if (*pvp != NULL && (**pvp & 0377) == CANONNET)
rwr = NULL;
+ }
}
else
{
@@ -1173,6 +1220,8 @@ rewrite(pvp, ruleset, e)
** tv -- token vector.
** a -- pointer to address descriptor to fill.
** If NULL, one will be allocated.
+** flags -- info regarding whether this is a sender or
+** a recipient.
** e -- the current envelope.
**
** Returns:
@@ -1203,26 +1252,45 @@ struct errcodes
};
ADDRESS *
-buildaddr(tv, a, e)
+buildaddr(tv, a, flags, e)
register char **tv;
register ADDRESS *a;
+ int flags;
register ENVELOPE *e;
{
struct mailer **mp;
register struct mailer *m;
char *bp;
int spaceleft;
+ static MAILER errormailer;
+ static char *errorargv[] = { "ERROR", NULL };
static char buf[MAXNAME];
+ if (tTd(24, 5))
+ {
+ printf("buildaddr, flags=%o, tv=", flags);
+ printav(tv);
+ }
+
if (a == NULL)
a = (ADDRESS *) xalloc(sizeof *a);
bzero((char *) a, sizeof *a);
/* figure out what net/mailer to use */
- if ((**tv & 0377) != CANONNET)
+ if (*tv == NULL || (**tv & 0377) != CANONNET)
{
syserr("554 buildaddr: no net");
- return (NULL);
+badaddr:
+ a->q_flags |= QBADADDR;
+ a->q_mailer = &errormailer;
+ if (errormailer.m_name == NULL)
+ {
+ /* initialize the bogus mailer */
+ errormailer.m_name = "*error*";
+ errormailer.m_mailer = "ERROR";
+ errormailer.m_argv = errorargv;
+ }
+ return a;
}
tv++;
if (strcasecmp(*tv, "error") == 0)
@@ -1244,12 +1312,28 @@ buildaddr(tv, a, e)
}
tv++;
}
+ else
+ setstat(EX_UNAVAILABLE);
if ((**tv & 0377) != CANONUSER)
syserr("554 buildaddr: error: no user");
cataddr(++tv, NULL, buf, sizeof buf, ' ');
stripquotes(buf);
- usrerr(buf);
- return (NULL);
+ if (isascii(buf[0]) && isdigit(buf[0]) &&
+ isascii(buf[1]) && isdigit(buf[1]) &&
+ isascii(buf[2]) && isdigit(buf[2]) &&
+ buf[3] == ' ')
+ {
+ char fmt[10];
+
+ strncpy(fmt, buf, 3);
+ strcpy(&fmt[3], " %s");
+ usrerr(fmt, buf + 4);
+ }
+ else
+ {
+ usrerr("553 %s", buf);
+ }
+ goto badaddr;
}
for (mp = Mailer; (m = *mp++) != NULL; )
@@ -1260,7 +1344,7 @@ buildaddr(tv, a, e)
if (m == NULL)
{
syserr("554 buildaddr: unknown mailer %s", *tv);
- return (NULL);
+ goto badaddr;
}
a->q_mailer = m;
@@ -1297,7 +1381,7 @@ buildaddr(tv, a, e)
if (!bitnset(M_LOCALMAILER, m->m_flags))
{
syserr("554 buildaddr: no host");
- return (NULL);
+ goto badaddr;
}
a->q_host = NULL;
}
@@ -1306,7 +1390,7 @@ buildaddr(tv, a, e)
if (*tv == NULL || (**tv & 0377) != CANONUSER)
{
syserr("554 buildaddr: no user");
- return (NULL);
+ goto badaddr;
}
tv++;
@@ -1342,8 +1426,16 @@ buildaddr(tv, a, e)
a->q_flags |= QNOTREMOTE;
}
- /* do cleanup of final address */
- (void) rewrite(tv, 4, e);
+ /* rewrite according recipient mailer rewriting rules */
+ define('h', a->q_host, e);
+ if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
+ {
+ /* sender addresses done later */
+ (void) rewrite(tv, 2, 0, e);
+ if (m->m_re_rwset > 0)
+ (void) rewrite(tv, m->m_re_rwset, 0, e);
+ }
+ (void) rewrite(tv, 4, 0, e);
/* save the result for the command line/RCPT argument */
cataddr(tv, NULL, buf, sizeof buf, '\0');
@@ -1437,6 +1529,8 @@ sameaddr(a, b)
register ADDRESS *a;
register ADDRESS *b;
{
+ register ADDRESS *ca, *cb;
+
/* if they don't have the same mailer, forget it */
if (a->q_mailer != b->q_mailer)
return (FALSE);
@@ -1445,9 +1539,16 @@ sameaddr(a, b)
if (strcmp(a->q_user, b->q_user) != 0)
return (FALSE);
- /* if we have good uids for both but the differ, these are different */
- if (bitset(QGOODUID, a->q_flags & b->q_flags) && a->q_uid != b->q_uid)
- return (FALSE);
+ /* if we have good uids for both but they differ, these are different */
+ if (a->q_mailer == ProgMailer)
+ {
+ ca = getctladdr(a);
+ cb = getctladdr(b);
+ if (ca != NULL && cb != NULL &&
+ bitset(QGOODUID, ca->q_flags & cb->q_flags) &&
+ ca->q_uid != cb->q_uid)
+ return (FALSE);
+ }
/* otherwise compare hosts (but be careful for NULL ptrs) */
if (a->q_host == b->q_host)
@@ -1592,10 +1693,10 @@ remotename(name, m, flags, pstat, e)
** domain will be appended.
*/
- pvp = prescan(name, '\0', pvpbuf, NULL);
+ pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL);
if (pvp == NULL)
return (name);
- if (rewrite(pvp, 3, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
*pstat = EX_TEMPFAIL;
if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL)
{
@@ -1612,7 +1713,7 @@ remotename(name, m, flags, pstat, e)
while ((*pxp++ = *qxq++) != NULL)
continue;
- if (rewrite(pvp, 3, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
*pstat = EX_TEMPFAIL;
}
}
@@ -1626,17 +1727,17 @@ remotename(name, m, flags, pstat, e)
if (bitset(RF_SENDERADDR, flags))
{
- if (rewrite(pvp, 1, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 1, 0, e) == EX_TEMPFAIL)
*pstat = EX_TEMPFAIL;
}
else
{
- if (rewrite(pvp, 2, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 2, 0, e) == EX_TEMPFAIL)
*pstat = EX_TEMPFAIL;
}
if (rwset > 0)
{
- if (rewrite(pvp, rwset, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, rwset, 0, e) == EX_TEMPFAIL)
*pstat = EX_TEMPFAIL;
}
@@ -1647,7 +1748,7 @@ remotename(name, m, flags, pstat, e)
** may be used as a default to the above rules.
*/
- if (rewrite(pvp, 4, e) == EX_TEMPFAIL)
+ if (rewrite(pvp, 4, 0, e) == EX_TEMPFAIL)
*pstat = EX_TEMPFAIL;
/*
@@ -1656,7 +1757,13 @@ remotename(name, m, flags, pstat, e)
cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0');
define('g', lbuf, e);
- expand(fancy, buf, &buf[sizeof buf - 1], e);
+
+ /* need to make sure route-addrs have <angle brackets> */
+ if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
+ expand("<\201g>", buf, &buf[sizeof buf - 1], e);
+ else
+ expand(fancy, buf, &buf[sizeof buf - 1], e);
+
define('g', oldg, e);
if (tTd(12, 1))
@@ -1690,16 +1797,16 @@ maplocaluser(a, sendq, e)
printf("maplocaluser: ");
printaddr(a, FALSE);
}
- pvp = prescan(a->q_user, '\0', pvpbuf, &delimptr);
+ pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr);
if (pvp == NULL)
return;
- (void) rewrite(pvp, 5, e);
+ (void) rewrite(pvp, 5, 0, e);
if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
return;
/* if non-null, mailer destination specified -- has it changed? */
- a1 = buildaddr(pvp, NULL, e);
+ a1 = buildaddr(pvp, NULL, 0, e);
if (a1 == NULL || sameaddr(a, a1))
return;
@@ -1711,7 +1818,7 @@ maplocaluser(a, sendq, e)
printaddr(a, FALSE);
}
a1->q_alias = a;
- allocaddr(a1, 1, NULL, delimptr);
+ allocaddr(a1, RF_COPYALL, NULL);
(void) recipient(a1, sendq, e);
}
/*