diff options
Diffstat (limited to 'usr.sbin/sendmail/src/udb.c')
-rw-r--r-- | usr.sbin/sendmail/src/udb.c | 240 |
1 files changed, 61 insertions, 179 deletions
diff --git a/usr.sbin/sendmail/src/udb.c b/usr.sbin/sendmail/src/udb.c index d2b60fc..4739a08 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 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -35,30 +35,21 @@ #include "sendmail.h" #ifndef lint -#if USERDB -static char sccsid [] = "@(#)udb.c 8.32 (Berkeley) 11/18/95 (with USERDB)"; +#ifdef USERDB +static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (with USERDB)"; #else -static char sccsid [] = "@(#)udb.c 8.32 (Berkeley) 11/18/95 (without USERDB)"; +static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (without USERDB)"; #endif #endif -#if USERDB +#ifdef USERDB #include <errno.h> - -#ifdef NEWDB -# include <db.h> -#else -# define DBT struct _data_base_thang_ -DBT -{ - void *data; /* pointer to data */ - size_t size; /* length of data */ -}; -#endif +#include <netdb.h> +#include <db.h> #ifdef HESIOD -# include <hesiod.h> +#include <hesiod.h> #endif /* HESIOD */ /* @@ -91,7 +82,6 @@ struct udbent } udb_forward; #define udb_fwdhost udb_u.udb_forward._udb_fwdhost -#ifdef NEWDB /* type UE_FETCH -- lookup in local database */ struct { @@ -100,7 +90,6 @@ struct udbent } udb_lookup; #define udb_dbname udb_u.udb_lookup._udb_dbname #define udb_dbp udb_u.udb_lookup._udb_dbp -#endif } udb_u; }; @@ -125,8 +114,6 @@ struct option ** Parameters: ** a -- address to expand. ** sendq -- pointer to head of sendq to put the expansions in. -** aliaslevel -- the current alias nesting depth. -** e -- the current envelope. ** ** Returns: ** EX_TEMPFAIL -- if something "odd" happened -- probably due @@ -145,13 +132,13 @@ int UdbSock = -1; bool UdbInitialized = FALSE; int -udbexpand(a, sendq, aliaslevel, e) +udbexpand(a, sendq, e) register ADDRESS *a; ADDRESS **sendq; - int aliaslevel; register ENVELOPE *e; { int i; + register char *p; DBT key; DBT info; bool breakout; @@ -214,7 +201,6 @@ udbexpand(a, sendq, aliaslevel, e) switch (up->udb_type) { -#ifdef NEWDB case UDB_DBFETCH: key.data = keybuf; key.size = keylen; @@ -241,6 +227,7 @@ udbexpand(a, sendq, aliaslevel, e) if (bitset(EF_VRFYONLY, e->e_flags)) { a->q_flags |= QVERIFIED; + e->e_nrcpts++; return EX_OK; } @@ -255,11 +242,12 @@ udbexpand(a, sendq, aliaslevel, e) 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)); + syslog(LOG_INFO, "%s: expand %s => %s", + e->e_id, e->e_to, user); #endif - naddrs += sendtolist(user, a, sendq, aliaslevel + 1, e); + AliasLevel++; + naddrs += sendtolist(user, a, sendq, e); + AliasLevel--; if (user != buf) free(user); @@ -311,11 +299,9 @@ udbexpand(a, sendq, aliaslevel, e) fprintf(e->e_xfp, "Message delivered to mailing list %s\n", a->q_paddr); + e->e_flags |= EF_SENDRECEIPT; } - e->e_flags |= EF_SENDRECEIPT; - a->q_flags |= QDELIVERED|QEXPANDED; break; -#endif #ifdef HESIOD case UDB_HESIOD: @@ -326,45 +312,12 @@ udbexpand(a, sendq, aliaslevel, e) keybuf, keylen); /* look up the key via hesiod */ i = hes_udb_get(&key, &info); - if (i < 0) - { - syserr("udbexpand: hesiod-get %.*s stat %d", - key.size, key.data, i); - return EX_TEMPFAIL; - } - else if (i > 0 || info.size <= 0) + if (i > 0 || info.size <= 0) { -#if HES_GETMAILHOST - struct hes_postoffice *hp; -#endif - if (tTd(28, 2)) - printf("udbexpand: no match on %s (%d)\n", - keybuf, keylen); -#if HES_GETMAILHOST - if (tTd(28, 8)) - printf(" ... trying hes_getmailhost(%s)\n", - a->q_user); - hp = hes_getmailhost(a->q_user); - if (hp == NULL) - { - if (hes_error() == HES_ER_NET) - { - syserr("udbexpand: hesiod-getmail %s stat %d", - a->q_user, hes_error()); - return EX_TEMPFAIL; - } - if (tTd(28, 2)) - printf("hes_getmailhost(%s): %d\n", - a->q_user, hes_error(); - continue; - } - sprintf(info.data, "%s@%s", - hp->po_name, hp->po_host); - info.size = strlen(info.data); -#else + printf("udbexpand: no match on %s (%d)\n", + keybuf, keylen); continue; -#endif } if (tTd(28, 80)) printf("udbexpand: match %.*s: %.*s\n", @@ -374,6 +327,8 @@ udbexpand(a, sendq, aliaslevel, e) if (bitset(EF_VRFYONLY, e->e_flags)) { a->q_flags |= QVERIFIED; + e->e_nrcpts++; + free(info.data); return EX_OK; } @@ -384,15 +339,17 @@ udbexpand(a, sendq, aliaslevel, e) user = xalloc(info.size + 1); bcopy(info.data, user, info.size); user[info.size] = '\0'; + free(info.data); message("hesioded to %s", user); #ifdef LOG if (LogLevel >= 10) - syslog(LOG_INFO, "%s: hesiod %.100s => %s", - e->e_id, e->e_to, - shortenstring(user, 203)); + syslog(LOG_INFO, "%s: hesiod %s => %s", + e->e_id, e->e_to, user); #endif - naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e); + AliasLevel++; + naddrs = sendtolist(user, a, sendq, e); + AliasLevel--; if (user != buf) free(user); @@ -406,6 +363,12 @@ udbexpand(a, sendq, aliaslevel, e) } a->q_flags |= QDONTSEND; } + if (i < 0) + { + syserr("udbexpand: hesiod-get %.*s stat %d", + key.size, key.data, i); + return EX_TEMPFAIL; + } /* ** If this address has a -request address, reflect @@ -423,6 +386,7 @@ udbexpand(a, sendq, aliaslevel, e) a->q_owner = xalloc(info.size + 1); bcopy(info.data, a->q_owner, info.size); a->q_owner[info.size] = '\0'; + free(info.data); break; #endif /* HESIOD */ @@ -441,7 +405,9 @@ udbexpand(a, sendq, aliaslevel, e) (void) sprintf(user, "%s@%s", a->q_user, up->udb_fwdhost); message("expanded to %s", user); a->q_flags &= ~QSELFREF; - naddrs = sendtolist(user, a, sendq, aliaslevel + 1, e); + AliasLevel++; + naddrs = sendtolist(user, a, sendq, e); + AliasLevel--; if (naddrs > 0 && !bitset(QSELFREF, a->q_flags)) { if (tTd(28, 5)) @@ -543,7 +509,6 @@ udbmatch(user, field) switch (up->udb_type) { -#ifdef NEWDB case UDB_DBFETCH: key.data = keybuf; key.size = keylen; @@ -563,13 +528,12 @@ udbmatch(user, field) printf("udbmatch ==> %s\n", p); return p; break; -#endif #ifdef HESIOD case UDB_HESIOD: key.data = keybuf; key.size = keylen; - i = hes_udb_get(&key, &info); + i = hes_udb_get(&key, &info); if (i != 0 || info.size <= 0) { if (tTd(28, 2)) @@ -581,9 +545,11 @@ udbmatch(user, field) p = xalloc(info.size + 1); bcopy(info.data, p, info.size); p[info.size] = '\0'; + free(info.data); if (tTd(28, 1)) printf("udbmatch ==> %s\n", p); return p; + break; #endif /* HESIOD */ } } @@ -606,7 +572,6 @@ udbmatch(user, field) { switch (up->udb_type) { -#ifdef NEWDB case UDB_DBFETCH: /* get the default case for this database */ if (up->udb_default == NULL) @@ -648,7 +613,6 @@ udbmatch(user, field) printf("udbmatch ==> %s\n", p); return p; break; -#endif #ifdef HESIOD case UDB_HESIOD: @@ -657,7 +621,7 @@ udbmatch(user, field) { key.data = ":default:mailname"; key.size = strlen(key.data); - i = hes_udb_get(&key, &info); + i = hes_udb_get(&key, &info); if (i != 0 || info.size <= 0) { @@ -670,6 +634,7 @@ udbmatch(user, field) up->udb_default = xalloc(info.size + 1); bcopy(info.data, up->udb_default, info.size); up->udb_default[info.size] = '\0'; + free(info.data); } else if (up->udb_default[0] == '\0') continue; @@ -684,6 +649,7 @@ udbmatch(user, field) continue; } + free(info.data); /* they exist -- build the actual address */ p = xalloc(strlen(user) + strlen(up->udb_default) + 2); (void) strcpy(p, user); @@ -701,57 +667,6 @@ udbmatch(user, field) return NULL; } /* -** UDB_MAP_LOOKUP -- look up arbitrary entry in user database map -** -** Parameters: -** map -- the map being queried. -** name -- the name to look up. -** av -- arguments to the map lookup. -** statp -- to get any error status. -** -** Returns: -** NULL if name not found in map. -** The rewritten name otherwise. -*/ - -char * -udb_map_lookup(map, name, av, statp) - MAP *map; - char *name; - char **av; - int *statp; -{ - char *val; - char *key; - char keybuf[MAXNAME + 1]; - - if (tTd(28, 20) || tTd(38, 20)) - printf("udb_map_lookup(%s, %s)\n", map->map_mname, name); - - if (bitset(MF_NOFOLDCASE, map->map_mflags)) - { - key = name; - } - else - { - int keysize = strlen(name); - - if (keysize > sizeof keybuf - 1) - keysize = sizeof keybuf - 1; - bcopy(name, keybuf, keysize); - keybuf[keysize] = '\0'; - makelower(keybuf); - key = keybuf; - } - val = udbmatch(key, map->map_file); - if (val == NULL) - return NULL; - if (bitset(MF_MATCHONLY, map->map_mflags)) - return map_rewrite(map, name, strlen(name), NULL); - else - return map_rewrite(map, val, strlen(val), av); -} -/* ** _UDBX_INIT -- parse the UDB specification, opening any valid entries. ** ** Parameters: @@ -773,7 +688,9 @@ int _udbx_init() { register char *p; + int i; register struct udbent *up; + char buf[BUFSIZ]; if (UdbInitialized) return EX_OK; @@ -788,14 +705,11 @@ _udbx_init() while (p != NULL) { char *spec; - int nopts; -# if 0 auto int rcode; + int nopts; int nmx; - int i; register struct hostent *h; char *mxhosts[MAXMXHOSTS + 1]; -# endif struct option opts[MAXUDBOPTS + 1]; while (*p == ' ' || *p == '\t' || *p == ',') @@ -829,13 +743,10 @@ _udbx_init() ** since it always matches the input. ** /dbname -- search the named database on the local ** host using the Berkeley db package. - ** Hesiod -- search the named database with BIND - ** using the MIT Hesiod package. */ switch (*spec) { -#if 0 case '+': /* search remote database */ case '*': /* search remote database (expand MX) */ if (*spec == '*') @@ -865,14 +776,14 @@ _udbx_init() for (i = 0; i < nmx; i++) { - h = sm_gethostbyname(mxhosts[i]); + h = gethostbyname(mxhosts[i]); if (h == NULL) continue; up->udb_type = UDB_REMOTE; up->udb_addr.sin_family = h->h_addrtype; bcopy(h->h_addr_list[0], (char *) &up->udb_addr.sin_addr, - INADDRSZ); + sizeof up->udb_addr.sin_addr); up->udb_addr.sin_port = UdbPort; up->udb_timeout = UdbTimeout; up++; @@ -885,7 +796,6 @@ _udbx_init() (void) fcntl(UdbSock, F_SETFD, 1); } break; -#endif case '@': /* forward to remote host */ up->udb_type = UDB_FORWARD; @@ -893,31 +803,22 @@ _udbx_init() up++; break; -#ifdef HESIOD case 'h': /* use hesiod */ case 'H': +#ifdef HESIOD if (strcasecmp(spec, "hesiod") != 0) - goto badspec; + break; up->udb_type = UDB_HESIOD; up++; - break; #endif /* HESIOD */ + break; -#ifdef NEWDB case '/': /* look up remote name */ up->udb_dbname = spec; errno = 0; up->udb_dbp = dbopen(spec, O_RDONLY, 0644, DB_BTREE, NULL); if (up->udb_dbp == NULL) { - if (tTd(28, 1)) - { - int saveerrno = errno; - - printf("dbopen(%s): %s", - spec, errstring(errno)); - errno = saveerrno; - } if (errno != ENOENT && errno != EACCES) { #ifdef LOG @@ -933,12 +834,6 @@ _udbx_init() up->udb_type = UDB_DBFETCH; up++; break; -#endif - - default: -badspec: - syserr("Unknown UDB spec %s", spec); - break; } } up->udb_type = UDB_EOLIST; @@ -949,21 +844,15 @@ badspec: { switch (up->udb_type) { -#ifdef DAEMON case UDB_REMOTE: printf("REMOTE: addr %s, timeo %d\n", anynet_ntoa((SOCKADDR *) &up->udb_addr), up->udb_timeout); break; -#endif case UDB_DBFETCH: -#ifdef NEWDB printf("FETCH: file %s\n", up->udb_dbname); -#else - printf("FETCH\n"); -#endif break; case UDB_FORWARD: @@ -991,7 +880,6 @@ badspec: */ tempfail: -#ifdef NEWDB for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++) { if (up->udb_type == UDB_DBFETCH) @@ -999,7 +887,6 @@ badspec: (*up->udb_dbp->close)(up->udb_dbp); } } -#endif return EX_TEMPFAIL; } @@ -1042,24 +929,20 @@ hes_udb_get(key, info) { char *name, *type; char *p, **hp; - char kbuf[MAXKEY + 1]; - strcpy(kbuf, key->data); - name = kbuf; - type = strrchr(name, ':'); + name = key->data; + type = strchr(name, ':'); if (type == NULL) return 1; + *type++ = '\0'; - if (strchr(name, '@') != NULL) - return 1; if (tTd(28, 1)) printf("hes_udb_get(%s, %s)\n", name, type); /* make the hesiod query */ hp = hes_resolve(name, type); - *--type = ':'; - if (hp == NULL || hp[0] == NULL) + if (hp == NULL) { /* network problem or timeout */ if (hes_error() == HES_ER_NET) @@ -1071,19 +954,19 @@ hes_udb_get(key, info) { /* ** If there are multiple matches, just return the - ** first one. + ** first one and free the others. ** ** XXX These should really be returned; for example, ** XXX it is legal for :maildrop to be multi-valued. */ + for (p = hp[1]; p; p++) + free(p); + info->data = hp[0]; info->size = (size_t) strlen(info->data); } - if (tTd(28, 80)) - printf("hes_udb_get => %s\n", *hp); - return 0; } #endif /* HESIOD */ @@ -1091,10 +974,9 @@ hes_udb_get(key, info) #else /* not USERDB */ int -udbexpand(a, sendq, aliaslevel, e) +udbexpand(a, sendq, e) ADDRESS *a; ADDRESS **sendq; - int aliaslevel; ENVELOPE *e; { return EX_OK; |