/*
 * Copyright (c) 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: localuser.c,v 1.7 2007/11/14 06:03:08 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/io.h"
#include "sm/net.h"
#include "sm/mta.h"
#include "sm/rfc2821.h"
#include "smar.h"
#include "log.h"

/*
**  SMAR_ADDR_LU -- Check whether local part is in "alias" or "local user" map
**
**	Parameters:
**		smar_ctx -- SMAR context
**		user -- user part of address
**		delim -- delimiter used in address
**		detail -- detail part of address
**			must be NULL iff if there is no "delim" in the address
**		domain -- domain part of address
**		rhs -- string for lookups (to return rhs)
**		pstatus -- (pointer to) status (output)
**
**	Returns:
**		usual sm_error code
**
**	Last code review:
**	Last code change:
*/

sm_ret_T
smar_addr_lu(smar_ctx_P smar_ctx, sm_str_P user, uchar delim, sm_str_P detail, sm_str_P domain, sm_str_P rhs, uint32_t *pstatus)
{
	sm_ret_T ret;
	uint32_t lfl;

	SM_IS_SMAR_CTX(smar_ctx);
	SM_REQUIRE(user != NULL);
	SM_REQUIRE(pstatus != NULL);

	lfl = smar_ctx->smar_alias_lfl;
	if (detail == NULL)
		lfl &= ~SMMAP_LFL_DET;
	ret = sm_map_lookup_addr(smar_ctx->smar_aliases, user, detail,
		(domain == NULL || sm_str_getlen(domain) == 0) ? NULL : domain,
		/* tag */ NULL,
		delim, lfl, rhs);

SMAR_LEV_DPRINTF(3, (SMAR_DEBFP, "func=smar_addr_lu, local=%S, detail=%S, domain=%S, rhs=%.256S, lfl=%#x, ret=%r\n", user, detail, domain, rhs, lfl, ret));

	if (sm_is_success(ret)
	    && sm_str_getlen(rhs) >= RHS_ERROR_LEN
	    && strncasecmp((const char*) sm_str_data(rhs),
			RHS_ERROR, RHS_ERROR_LEN) == 0)
	{
		/* don't accept mail for this address */
		if (sm_str_getlen(rhs) >= RHS_ERROR_4_LEN
		    && strncasecmp((const char*) sm_str_data(rhs),
			RHS_ERROR_4, RHS_ERROR_4_LEN) == 0)
		{
			*pstatus = SMTP_R_TEMP;
		}
		else
		{
			*pstatus = SMTP_R_REJECT;
		}
	}
	else if (ret == sm_error_perm(SM_EM_BDB, ENOMEM) ||
		 ret == SM_MAP_DATA2BIG)
	{
		/* found address, but it's too long for rhs: accept */
		*pstatus = SMTP_R_CONT;
	}
	else if (sm_is_err(ret) && smar_ctx->smar_lum != NULL)
	{
		lfl = smar_ctx->smar_lum_lfl;
		if (detail == NULL)
			lfl &= ~SMMAP_LFL_DET;
		ret = sm_map_lookup_addr(smar_ctx->smar_lum, user, detail,
			(domain == NULL || sm_str_getlen(domain) == 0) ? NULL : domain,
			/* tag */ NULL, delim, lfl, rhs);

SMAR_LEV_DPRINTF(3, (SMAR_DEBFP, "func=smar_addr_lu, local=%S, detail=%S, rhs=%.256S, local_map_lookup=%r\n", user, detail, rhs, ret));
		*pstatus = (ret == SM_SUCCESS)
			? SMTP_R_CONT
			: (sm_is_temp_err(ret) ? SMTP_R_TEMP
				: SMTP_R_REJECT);
	}
	else
		*pstatus = sm_is_success(ret) ? SMTP_R_CONT : SMTP_R_REJECT;
	return ret;
}


syntax highlighted by Code2HTML, v. 0.9.1