/* * 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: mtinit.c,v 1.19 2006/11/10 03:46:11 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/ctype.h" #include "sm/io.h" #include "sm/net.h" #include "sm/misc.h" #include "sm/smardef.h" #include "sm/confsetpath.h" #include "smar.h" #include "log.h" /* ** SMAR_MT_INIT -- initialize "mailertable". This is a hack. ** ** Parameters: ** smar_ctx -- SMAR context ** ** Returns: ** usual sm_error code */ sm_ret_T smar_mt_init(smar_ctx_P smar_ctx) { sm_ret_T ret; sm_file_T *fp; int c, i, hl; const char *mpath; char hn[256], *hna; char ipv4[128], *ipv4a, *addr, *eos; sm_str_T key, data; char confdir[PATH_MAX]; SM_IS_SMAR_CTX(smar_ctx); ret = sm_dirname(smar_ctx->smar_cnf.smar_cnf_conffile, confdir, sizeof(confdir)); if (sm_is_err(ret)) goto error; SM_GEN_MAP_PATH(mpath, smar_ctx->smar_cnf.smar_cnf_mt_path, confdir, smar_ctx->smar_cnf.smar_cnf_mt_fn, SMAR_MT_NAME, error); fp = NULL; ret = sm_io_open(SmStStdio, mpath, SM_IO_RDONLY, &fp, SM_IO_WHAT_END); if (sm_is_err(ret)) goto error; while (!sm_eof(fp)) { i = 0; /* read hostname/domain literal */ if (SMAR_MT_FULL_LOOKUP(smar_ctx)) { /* note: this isn't correct: it could be a quoted space... */ while ((c = sm_io_getc(fp)) != SM_IO_EOF && !ISSPACE(c)) { hn[i++] = (char) c; if (i >= (int) sizeof(hn)) goto syntax; } } else { while ((c = sm_io_getc(fp)) != SM_IO_EOF && (ISALNUM(c) || c == '.' || c == '-' || (c == '[' && i == 0) || (c == ']' && i > 0))) { hn[i++] = (char) c; if (i >= (int) sizeof(hn)) goto syntax; } } if (c == SM_IO_EOF && i == 0) break; if (c == SM_IO_EOF || !ISSPACE(c)) goto syntax; hn[i++] = '\0'; hna = (char *) sm_malloc(i + 1); if (hna == NULL) goto enomem; strlcpy(hna, hn, i); hl = i - 1; /* skip over whitespace */ while ((c = sm_io_getc(fp)) != SM_IO_EOF && ISSPACE(c)) ; if (c != SM_IO_EOF) sm_io_ungetc(fp, c); /* read RHS and check syntax */ i = 0; while ((c = sm_io_getc(fp)) != SM_IO_EOF && (ISALNUM(c) || c == '.' || c == '-' || c == '[' || c == ']' || c == ':' || c == SMAR_RHS_SEP_C || c == SMAR_RHS_PORT_C || c == SMAR_RHS_PROT_C )) { ipv4[i++] = (char) c; if (i >= (int) sizeof(ipv4)) goto syntax; } ipv4[i++] = '\0'; if (c == SM_IO_EOF || !ISSPACE(c)) { sm_log_write(smar_ctx->smar_lctx, AR_LCAT_INIT, AR_LMOD_CONFIG, SM_LOG_ERROR, 0, "sev=ERROR, func=smar_mt_init, syntax_error_rhs=\"%.256s\"", ipv4); goto syntax; } ipv4a = (char *) sm_malloc(i); if (ipv4a == NULL) goto enomem; strlcpy(ipv4a, ipv4, i); eos = ipv4a + i; for (addr = ipv4a; *addr != '\0' && addr < eos; ++addr) { if (*addr == '[') { ret = sm_inet_a2ipv4(addr, NULL, NULL); if (sm_is_err(ret)) { sm_log_write(smar_ctx->smar_lctx, AR_LCAT_INIT, AR_LMOD_CONFIG, SM_LOG_ERROR, 0, "sev=ERROR, func=smar_mt_init, not_an_IPv4_address=\"%.256s\", input=%.256s", addr, ipv4a); ret = sm_error_perm(SM_EM_AR, errno); goto error; } } /* skip to end of address */ while (*addr != '\0' && *addr != SMAR_RHS_SEP_C && addr < eos) ++addr; if (*addr == '\0') break; } sm_str_assign(key, NULL, (uchar *)hna, hl, hl + 2); sm_str_assign(data, NULL, (uchar *)ipv4a, i, i + 2); ret = sm_map_add(smar_ctx->smar_mt_map, &key, &data, SMMAP_AFL_UNIQUE); if (sm_is_err(ret)) goto error; } sm_io_close(fp, SM_IO_CF_NONE); return SM_SUCCESS; enomem: ret = sm_error_temp(SM_EM_AR, ENOMEM); goto error; syntax: ret = sm_error_perm(SM_EM_AR, SM_E_SYNTAX); error: if (fp != NULL) sm_io_close(fp, SM_IO_CF_NONE); return ret; }