/*++ /* NAME /* resolve_local 3 /* SUMMARY /* determine if domain resolves to local mail system /* SYNOPSIS /* #include <resolve_local.h> /* /* void resolve_local_init() /* /* int resolve_local(domain) /* const char *domain; /* DESCRIPTION /* resolve_local() determines if the named domain resolves to the /* local mail system, either by case-insensitive exact match /* against the domains, files or tables listed in $mydestination, /* or by any of the network addresses listed in $inet_interfaces /* or in $proxy_interfaces. /* /* resolve_local_init() performs initialization. If this routine is /* not called explicitly ahead of time, it will be called on the fly. /* BUGS /* Calling resolve_local_init() on the fly is an incomplete solution. /* It is bound to fail with applications that enter a chroot jail. /* SEE ALSO /* own_inet_addr(3), find out my own network interfaces /* match_list(3), generic pattern matching engine /* match_ops(3), generic pattern matching operators /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /*--*/ /* System library. */ #include <sys_defs.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif /* Utility library. */ #include <msg.h> #include <mymalloc.h> #include <string_list.h> /* Global library. */ #include <mail_params.h> #include <own_inet_addr.h> #include <resolve_local.h> #include <match_parent_style.h> /* Application-specific */ static STRING_LIST *resolve_local_list; /* resolve_local_init - initialize lookup table */ void resolve_local_init(void) { if (resolve_local_list) msg_panic("resolve_local_init: duplicate initialization"); resolve_local_list = string_list_init(MATCH_FLAG_NONE, var_mydest); } /* resolve_local - match domain against list of local destinations */ int resolve_local(const char *addr) { char *saved_addr = mystrdup(addr); char *dest; struct in_addr ipaddr; int len; #define RETURN(x) { myfree(saved_addr); return(x); } if (resolve_local_list == 0) resolve_local_init(); /* * Strip one trailing dot but not dot-dot. * * XXX This should not be distributed all over the code. Problem is, * addresses can enter the system via multiple paths: networks, local * forward/alias/include files, even as the result of address rewriting. */ len = strlen(saved_addr); if (len == 0) RETURN(0); if (saved_addr[len - 1] == '.') saved_addr[--len] = 0; if (len == 0 || saved_addr[len - 1] == '.') RETURN(0); /* * Compare the destination against the list of destinations that we * consider local. */ if (string_list_match(resolve_local_list, saved_addr)) RETURN(1); /* * Compare the destination against the list of interface addresses that * we are supposed to listen on. */ dest = saved_addr; if (*dest == '[' && dest[len - 1] == ']') { dest++; dest[len -= 2] = 0; if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr))) RETURN(1); } /* * Must be remote, or a syntax error. */ RETURN(0); } #ifdef TEST #include <vstream.h> #include <mail_conf.h> int main(int argc, char **argv) { if (argc != 2) msg_fatal("usage: %s domain", argv[0]); mail_conf_read(); vstream_printf("%s\n", resolve_local(argv[1]) ? "yes" : "no"); vstream_fflush(VSTREAM_OUT); } #endif