/* * Copyright (c) 2004, 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: pmilter_api.c,v 1.13 2006/10/05 04:27:37 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/types.h" #include "sm/fcntl.h" #include "sm/io.h" #include "sm/ctype.h" #include "sm/reccom.h" #include "sm/mta.h" #define PMILTER_DEBUG_DEFINE 1 #include "pmilter.h" #include "sm/pmilter.h" #include "sm/pmfapi.h" #include "util.h" #if MTA_USE_PMILTER /* ** SM_PMFI_VERSION -- return version of libpmilter ** ** Parameters: ** pmg_ctx -- pmilter (library) context ** major -- (pointer to) major version number of libpmilter ** minor -- (pointer to) minor version number of libpmilter ** patchlevel -- (pointer to) patchlevel of libpmilter ** ** Returns: ** usual sm_error code */ sm_ret_T sm_pmfi_version(pmg_ctx_P pmg_ctx, uint32_t *major, uint32_t *minor, uint32_t *patchlevel) { SM_REQUIRE(major != NULL); SM_REQUIRE(minor != NULL); SM_REQUIRE(patchlevel != NULL); *major = LPMILTER_VERSION_MAJOR; *minor = LPMILTER_VERSION_MINOR; *patchlevel = LPMILTER_VERSION_PL; return SM_SUCCESS; } /* ** SM_PMFI_SETCONN -- set pathname of socket ** ** Parameters: ** pmg_ctx -- pmilter (library) context ** path -- pathname of socket to use ** ** Returns: ** usual sm_error code */ sm_ret_T sm_pmfi_setconn(pmg_ctx_P pmg_ctx, const char *path) { SM_IS_PMG_CTX(pmg_ctx); SM_REQUIRE(path != NULL); /* memory leak if called multiple times. */ pmg_ctx->pmg_sockname = strdup(path); if (pmg_ctx->pmg_sockname == NULL) return sm_err_temp(ENOMEM); return SM_PMI_SUCCESS; } /* ** SM_PMFI_INIT -- initialize PMILTER library ** ** Parameters: ** ppmg_ctx -- (pointer to) pmilter (library) context (output) ** ** Returns: ** usual sm_error code */ sm_ret_T sm_pmfi_init(pmg_ctx_P *ppmg_ctx) { sm_ret_T ret; if (getuid() == 0 || geteuid() == 0) { sm_io_fprintf(smioerr, "ERROR: do not run this as super-user!\n"); return sm_err_perm(EPERM); } /* basic initialization */ ret = sm_pmilt_init0(ppmg_ctx); #if SM_HEAP_CHECK SmHeapCheck = 1; if (HEAP_CHECK) sm_heap_report(smioerr, 3); #endif return ret; } /* ** SM_PMFI_START -- start PMILTER ** ** Parameters: ** pmg_ctx -- pmilter (library) context ** pmilter -- pmilter application context ** ** Returns: ** exit code */ sm_ret_T sm_pmfi_start(pmg_ctx_P pmg_ctx, pmilter_P pmilter) { sm_ret_T ret; SM_IS_PMG_CTX(pmg_ctx); SM_REQUIRE(pmilter != NULL); if (getuid() == 0 || geteuid() == 0) { sm_io_fprintf(smioerr, "ERROR: do not run this as super-user!\n"); return EPERM; } pmg_ctx->pmg_pmilter = pmilter; if (SM_PM_VRS_MAJOR(pmilter->pmfi_version) != LPMILTER_VERSION_MAJOR) { sm_io_fprintf(smioerr, "ERROR: major version numbers do not match [lib=%d, pmilter=%d]\n" , LPMILTER_VERSION_MAJOR , SM_PM_VRS_MAJOR(pmilter->pmfi_version)); return EINVAL; } /* initialize system */ ret = sm_pmilt_init1(pmg_ctx); if (sm_is_err(ret)) { sm_io_fprintf(smioerr, "sev=ERROR, sm_pmilt_init=%x\n", ret); goto error; } /* startup pmilt */ ret = sm_pmilt_start(pmg_ctx); if (sm_is_err(ret)) { sm_io_fprintf(smioerr, "sev=ERROR, sm_pmilt_start=%x\n", ret); goto error; } pmg_ctx->pmg_state = PMILT_ST_RUN; /* wait for events, schedule tasks */ ret = evthr_loop(pmg_ctx->pmg_ev_ctx); pmg_ctx->pmg_state = PMILT_ST_STOPPING; ret = sm_pmilt_stop(pmg_ctx); pmg_ctx->pmg_state = PMILT_ST_STOPPED; #if SM_HEAP_CHECK if (HEAP_CHECK) sm_heap_report(smioerr, 3); #endif return SM_PMI_SUCCESS; error: /* ignore shutdown errors... */ (void) sm_pmilt_stop(pmg_ctx); /* select an appropriate error here... */ return sm_error_value(ret); } /* ** SM_PMFI_STOP -- stop PMILTER ** ** Parameters: ** pmg_ctx -- pmilter (library) context ** ** Returns: ** usual sm_error code */ sm_ret_T sm_pmfi_stop(pmg_ctx_P pmg_ctx) { SM_IS_PMG_CTX(pmg_ctx); return sm_pmilt_stop(pmg_ctx); } /* ** SM_PMFI_SETDBG -- set debug level ** ** Parameters: ** pmg_ctx -- pmilter (library) context ** debuglevel -- debug level ** ** Returns: ** usual sm_error code */ sm_ret_T sm_pmfi_setdbg(pmg_ctx_P pmg_ctx, unsigned int debuglevel) { SM_IS_PMG_CTX(pmg_ctx); #if PMILTER_DEBUG pm_debug = debuglevel; #endif return SM_SUCCESS; } #endif /* MTA_USE_PMILTER */