summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src/udb.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/udb.c')
-rw-r--r--usr.sbin/sendmail/src/udb.c240
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;
OpenPOWER on IntegriCloud