⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udb.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983 Eric P. Allman * Copyright (c) 1988, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "sendmail.h"#ifndef lint#ifdef USERDBstatic char sccsid [] = "@(#)udb.c	8.8 (Berkeley) 4/14/94 (with USERDB)";#elsestatic char sccsid [] = "@(#)udb.c	8.8 (Berkeley) 4/14/94 (without USERDB)";#endif#endif#ifdef USERDB#include <errno.h>#include <netdb.h>#include <db.h>#ifdef HESIOD#include <hesiod.h>#endif /* HESIOD *//***  UDB.C -- interface between sendmail and Berkeley User Data Base.****	This depends on the 4.4BSD db package.*/struct udbent{	char	*udb_spec;		/* string version of spec */	int	udb_type;		/* type of entry */	char	*udb_default;		/* default host for outgoing mail */	union	{		/* type UE_REMOTE -- do remote call for lookup */		struct		{			struct sockaddr_in _udb_addr;	/* address */			int		_udb_timeout;	/* timeout */		} udb_remote;#define udb_addr	udb_u.udb_remote._udb_addr#define udb_timeout	udb_u.udb_remote._udb_timeout		/* type UE_FORWARD -- forward message to remote */		struct		{			char	*_udb_fwdhost;	/* name of forward host */		} udb_forward;#define udb_fwdhost	udb_u.udb_forward._udb_fwdhost		/* type UE_FETCH -- lookup in local database */		struct		{			char	*_udb_dbname;	/* pathname of database */			DB	*_udb_dbp;	/* open database ptr */		} udb_lookup;#define udb_dbname	udb_u.udb_lookup._udb_dbname#define udb_dbp		udb_u.udb_lookup._udb_dbp	} udb_u;};#define UDB_EOLIST	0	/* end of list */#define UDB_SKIP	1	/* skip this entry */#define UDB_REMOTE	2	/* look up in remote database */#define UDB_DBFETCH	3	/* look up in local database */#define UDB_FORWARD	4	/* forward to remote host */#define UDB_HESIOD	5	/* look up via hesiod */#define MAXUDBENT	10	/* maximum number of UDB entries */struct option{	char	*name;	char	*val;};/***  UDBEXPAND -- look up user in database and expand****	Parameters:**		a -- address to expand.**		sendq -- pointer to head of sendq to put the expansions in.****	Returns:**		EX_TEMPFAIL -- if something "odd" happened -- probably due**			to accessing a file on an NFS server that is down.**		EX_OK -- otherwise.****	Side Effects:**		Modifies sendq.*/int	UdbPort = 1616;int	UdbTimeout = 10;struct udbent	UdbEnts[MAXUDBENT + 1];int		UdbSock = -1;bool		UdbInitialized = FALSE;intudbexpand(a, sendq, e)	register ADDRESS *a;	ADDRESS **sendq;	register ENVELOPE *e;{	int i;	register char *p;	DBT key;	DBT info;	bool breakout;	register struct udbent *up;	int keylen;	int naddrs;	char keybuf[MAXKEY];	char buf[BUFSIZ];	if (tTd(28, 1))		printf("udbexpand(%s)\n", a->q_paddr);	/* make certain we are supposed to send to this address */	if (bitset(QDONTSEND|QVERIFIED, a->q_flags))		return EX_OK;	e->e_to = a->q_paddr;	/* on first call, locate the database */	if (!UdbInitialized)	{		extern int _udbx_init();		if (_udbx_init() == EX_TEMPFAIL)			return EX_TEMPFAIL;	}	/* short circuit the process if no chance of a match */	if (UdbSpec == NULL || UdbSpec[0] == '\0')		return EX_OK;	/* short circuit name begins with '\\' since it can't possibly match */	if (a->q_user[0] == '\\')		return EX_OK;	/* if name is too long, assume it won't match */	if (strlen(a->q_user) > sizeof keybuf - 12)		return EX_OK;	/* if name begins with a colon, it indicates our metadata */	if (a->q_user[0] == ':')		return EX_OK;	/* build actual database key */	(void) strcpy(keybuf, a->q_user);	(void) strcat(keybuf, ":maildrop");	keylen = strlen(keybuf);	breakout = FALSE;	for (up = UdbEnts; !breakout; up++)	{		char *user;		/*		**  Select action based on entry type.		**		**	On dropping out of this switch, "class" should		**	explain the type of the data, and "user" should		**	contain the user information.		*/		switch (up->udb_type)		{		  case UDB_DBFETCH:			key.data = keybuf;			key.size = keylen;			if (tTd(28, 80))				printf("udbexpand: trying %s (%d) via db\n",					keybuf, keylen);			i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_CURSOR);			if (i > 0 || info.size <= 0)			{				if (tTd(28, 2))					printf("udbexpand: no match on %s (%d)\n",						keybuf, keylen);				continue;			}			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)			{				if (bitset(EF_VRFYONLY, e->e_flags))				{					a->q_flags |= QVERIFIED;					e->e_nrcpts++;					return EX_OK;				}				breakout = TRUE;				if (info.size < sizeof buf)					user = buf;				else					user = xalloc(info.size + 1);				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 %s => %s",						e->e_id, e->e_to, user);#endif				AliasLevel++;				naddrs += sendtolist(user, a, sendq, e);				AliasLevel--;				if (user != buf)					free(user);				/* get the next record */				i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_NEXT);			}			/* if nothing ever matched, try next database */			if (!breakout)				continue;			if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))			{				if (tTd(28, 5))				{					printf("udbexpand: QDONTSEND ");					printaddr(a, FALSE);				}				a->q_flags |= QDONTSEND;			}			if (i < 0)			{				syserr("udbexpand: db-get %.*s stat %d",					key.size, key.data, i);				return EX_TEMPFAIL;			}			/*			**  If this address has a -request address, reflect			**  it into the envelope.			*/			(void) strcpy(keybuf, a->q_user);			(void) strcat(keybuf, ":mailsender");			keylen = strlen(keybuf);			key.data = keybuf;			key.size = keylen;			i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);			if (i != 0 || info.size <= 0)				break;			a->q_owner = xalloc(info.size + 1);			bcopy(info.data, a->q_owner, info.size);			a->q_owner[info.size] = '\0';			/* announce delivery; NORECEIPT bit set later */			if (e->e_xfp != NULL)			{				fprintf(e->e_xfp,					"Message delivered to mailing list %s\n",					a->q_paddr);				e->e_flags |= EF_SENDRECEIPT;			}			break;#ifdef HESIOD		  case UDB_HESIOD:			key.data = keybuf;			key.size = keylen;			if (tTd(28, 80))				printf("udbexpand: trying %s (%d) via hesiod\n",					keybuf, keylen);			/* look up the key via hesiod */			i = hes_udb_get(&key, &info);			if (i > 0 || info.size <= 0)			{				if (tTd(28, 2))				printf("udbexpand: no match on %s (%d)\n",					keybuf, keylen);				continue;			}			if (tTd(28, 80))				printf("udbexpand: match %.*s: %.*s\n",					key.size, key.data, info.size, info.data);			a->q_flags &= ~QSELFREF;			if (bitset(EF_VRFYONLY, e->e_flags))			{				a->q_flags |= QVERIFIED;				e->e_nrcpts++;				free(info.data);				return EX_OK;			}			breakout = TRUE;			if (info.size < sizeof buf)				user = buf;			else				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 %s => %s",					e->e_id, e->e_to, user);#endif			AliasLevel++;			naddrs = sendtolist(user, a, sendq, e);			AliasLevel--;			if (user != buf)				free(user);			if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))			{				if (tTd(28, 5))				{					printf("udbexpand: QDONTSEND ");					printaddr(a, FALSE);				}				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			**  it into the envelope.			*/			(void) strcpy(keybuf, a->q_user);			(void) strcat(keybuf, ":mailsender");			keylen = strlen(keybuf);			key.data = keybuf;			key.size = keylen;			i = hes_udb_get(&key, &info);			if (i != 0 || info.size <= 0)				break;			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 */		  case UDB_REMOTE:			/* not yet implemented */			continue;		  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) sprintf(user, "%s@%s", a->q_user, up->udb_fwdhost);			message("expanded to %s", user);			a->q_flags &= ~QSELFREF;			AliasLevel++;			naddrs = sendtolist(user, a, sendq, e);			AliasLevel--;			if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))			{				if (tTd(28, 5))				{					printf("udbexpand: QDONTSEND ");					printaddr(a, FALSE);				}				a->q_flags |= QDONTSEND;			}			if (user != buf)				free(user);			breakout = TRUE;			break;		  case UDB_EOLIST:			breakout = TRUE;			continue;		  default:			/* unknown entry type */			continue;		}	}	return EX_OK;}/***  UDBSENDER -- return canonical external name of sender, given local name****	Parameters:**		sender -- the name of the sender on the local machine.****	Returns:**		The external name for this sender, if derivable from the**			database.**		NULL -- if nothing is changed from the database.****	Side Effects:**		none.*/char *udbsender(sender)	char *sender;{	extern char *udbmatch();	return udbmatch(sender, "mailname");}char *udbmatch(user, field)	char *user;	char *field;{	register char *p;	register struct udbent *up;	int i;	int keylen;	DBT key, info;	char keybuf[MAXKEY];	if (tTd(28, 1))		printf("udbmatch(%s, %s)\n", user, field);	if (!UdbInitialized)	{		if (_udbx_init() == EX_TEMPFAIL)			return NULL;	}	/* short circuit if no spec */	if (UdbSpec == NULL || UdbSpec[0] == '\0')		return NULL;	/* short circuit name begins with '\\' since it can't possibly match */	if (user[0] == '\\')		return NULL;	/* long names can never match and are a pain to deal with */	if ((strlen(user) + strlen(field)) > sizeof keybuf - 4)		return NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -