diff options
Diffstat (limited to 'usr.sbin/sendmail/src/udb.c')
-rw-r--r-- | usr.sbin/sendmail/src/udb.c | 116 |
1 files changed, 72 insertions, 44 deletions
diff --git a/usr.sbin/sendmail/src/udb.c b/usr.sbin/sendmail/src/udb.c index e9834ebea082..075f197c8026 100644 --- a/usr.sbin/sendmail/src/udb.c +++ b/usr.sbin/sendmail/src/udb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1983, 1995 Eric P. Allman + * Copyright (c) 1983, 1995, 1996 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -36,9 +36,9 @@ #ifndef lint #if USERDB -static char sccsid [] = "@(#)udb.c 8.33.1.2 (Berkeley) 9/16/96 (with USERDB)"; +static char sccsid [] = "@(#)udb.c 8.42 (Berkeley) 9/18/96 (with USERDB)"; #else -static char sccsid [] = "@(#)udb.c 8.33.1.2 (Berkeley) 9/16/96 (without USERDB)"; +static char sccsid [] = "@(#)udb.c 8.42 (Berkeley) 9/18/96 (without USERDB)"; #endif #endif @@ -119,6 +119,8 @@ struct option char *name; char *val; }; + +extern int _udbx_init __P((void)); /* ** UDBEXPAND -- look up user in database and expand ** @@ -159,7 +161,6 @@ udbexpand(a, sendq, aliaslevel, e) int keylen; int naddrs; char keybuf[MAXKEY]; - char buf[BUFSIZ]; if (tTd(28, 1)) printf("udbexpand(%s)\n", a->q_paddr); @@ -172,8 +173,6 @@ udbexpand(a, sendq, aliaslevel, e) /* on first call, locate the database */ if (!UdbInitialized) { - extern int _udbx_init(); - if (_udbx_init() == EX_TEMPFAIL) return EX_TEMPFAIL; } @@ -187,7 +186,7 @@ udbexpand(a, sendq, aliaslevel, e) return EX_OK; /* if name is too long, assume it won't match */ - if (strlen(a->q_user) > sizeof keybuf - 12) + if (strlen(a->q_user) > (SIZE_T) sizeof keybuf - 12) return EX_OK; /* if name begins with a colon, it indicates our metadata */ @@ -203,6 +202,16 @@ udbexpand(a, sendq, aliaslevel, e) for (up = UdbEnts; !breakout; up++) { char *user; + int usersize; + int userleft; + char userbuf[MEMCHUNKSIZE]; +#if defined(HESIOD) && defined(HES_GETMAILHOST) + char pobuf[MAXNAME]; +#endif + + user = userbuf; + usersize = sizeof userbuf; + userleft = sizeof userbuf - 1; /* ** Select action based on entry type. @@ -227,17 +236,18 @@ udbexpand(a, sendq, aliaslevel, e) if (tTd(28, 2)) printf("udbexpand: no match on %s (%d)\n", keybuf, keylen); - continue; + break; } if (tTd(28, 80)) printf("udbexpand: match %.*s: %.*s\n", key.size, key.data, info.size, info.data); - naddrs = 0; a->q_flags &= ~QSELFREF; while (i == 0 && key.size == keylen && bcmp(key.data, keybuf, keylen) == 0) { + char *p; + if (bitset(EF_VRFYONLY, e->e_flags)) { a->q_flags |= QVERIFIED; @@ -245,24 +255,26 @@ udbexpand(a, sendq, aliaslevel, e) } breakout = TRUE; - if (info.size < sizeof buf) - user = buf; - else - user = xalloc(info.size + 1); + if (info.size >= userleft - 1) + { + char *nuser = xalloc(usersize + MEMCHUNKSIZE); + + bcopy(user, nuser, usersize); + if (user != userbuf) + free(user); + user = nuser; + usersize += MEMCHUNKSIZE; + userleft += MEMCHUNKSIZE; + } + p = &user[strlen(user)]; + if (p != user) + { + *p++ = ','; + userleft--; + } bcopy(info.data, user, info.size); user[info.size] = '\0'; - - message("expanded to %s", user); -#ifdef LOG - if (LogLevel >= 10) - syslog(LOG_INFO, "%s: expand %.100s => %s", - e->e_id, e->e_to, - shortenstring(user, 203)); -#endif - naddrs += sendtolist(user, a, sendq, aliaslevel + 1, e); - - if (user != buf) - free(user); + userleft -= info.size; /* get the next record */ i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_NEXT); @@ -270,8 +282,16 @@ udbexpand(a, sendq, aliaslevel, e) /* if nothing ever matched, try next database */ if (!breakout) - continue; + break; + message("expanded to %s", user); +#ifdef LOG + if (LogLevel >= 10) + syslog(LOG_INFO, "%s: expand %.100s => %s", + e->e_id, e->e_to, + shortenstring(user, 203)); +#endif + naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e); if (naddrs > 0 && !bitset(QSELFREF, a->q_flags)) { if (tTd(28, 5)) @@ -357,13 +377,24 @@ udbexpand(a, sendq, aliaslevel, e) if (tTd(28, 2)) printf("hes_getmailhost(%s): %d\n", a->q_user, hes_error()); - continue; + break; } + if (strlen(hp->po_name) + strlen(hp->po_host) > + sizeof pobuf - 2) + { + if (tTd(28, 2)) + printf("hes_getmailhost(%s): expansion too long: %.30s@%.30s\n", + a->q_user, + hp->po_name, + hp->po_host); + break; + } + info.data = pobuf; snprintf(pobuf, sizeof pobuf, "%s@%s", hp->po_name, hp->po_host); info.size = strlen(info.data); #else - continue; + break; #endif } if (tTd(28, 80)) @@ -378,9 +409,7 @@ udbexpand(a, sendq, aliaslevel, e) } breakout = TRUE; - if (info.size < sizeof buf) - user = buf; - else + if (info.size >= usersize) user = xalloc(info.size + 1); bcopy(info.data, user, info.size); user[info.size] = '\0'; @@ -394,9 +423,6 @@ udbexpand(a, sendq, aliaslevel, e) #endif naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e); - if (user != buf) - free(user); - if (naddrs > 0 && !bitset(QSELFREF, a->q_flags)) { if (tTd(28, 5)) @@ -428,17 +454,18 @@ udbexpand(a, sendq, aliaslevel, e) case UDB_REMOTE: /* not yet implemented */ - continue; + break; case UDB_FORWARD: if (bitset(EF_VRFYONLY, e->e_flags)) return EX_OK; i = strlen(up->udb_fwdhost) + strlen(a->q_user) + 1; - if (i < sizeof buf) - user = buf; - else - user = xalloc(i + 1); - (void) snprintf(user, i, "%s@%s", + if (i >= usersize) + { + usersize = i + 1; + user = xalloc(usersize); + } + (void) snprintf(user, usersize, "%s@%s", a->q_user, up->udb_fwdhost); message("expanded to %s", user); a->q_flags &= ~QSELFREF; @@ -452,19 +479,19 @@ udbexpand(a, sendq, aliaslevel, e) } a->q_flags |= QDONTSEND; } - if (user != buf) - free(user); breakout = TRUE; break; case UDB_EOLIST: breakout = TRUE; - continue; + break; default: /* unknown entry type */ - continue; + break; } + if (user != userbuf) + free(user); } return EX_OK; } @@ -798,6 +825,7 @@ _udbx_init() char *mxhosts[MAXMXHOSTS + 1]; # endif struct option opts[MAXUDBOPTS + 1]; + extern int _udb_parsespec __P((char *, struct option [], int)); while (*p == ' ' || *p == '\t' || *p == ',') p++; |