Mercurial > dnsbl
comparison src/dnsbl.cpp @ 76:81f1e400e8ab
start coding on new config syntax
author | carl |
---|---|
date | Sat, 16 Jul 2005 13:47:19 -0700 |
parents | 1142e46be550 |
children | 8487650c98ee |
comparison
equal
deleted
inserted
replaced
75:1142e46be550 | 76:81f1e400e8ab |
---|---|
10 -r port The port used to talk to our internal dns resolver processes | 10 -r port The port used to talk to our internal dns resolver processes |
11 -p port The port through which the MTA will connect to this milter. | 11 -p port The port through which the MTA will connect to this milter. |
12 -t sec The timeout value. | 12 -t sec The timeout value. |
13 -c Check the config, and print a copy to stdout. Don't start the | 13 -c Check the config, and print a copy to stdout. Don't start the |
14 milter or do anything with the socket. | 14 milter or do anything with the socket. |
15 -s Stress test by loading and deleting the current config in a loop. | |
15 -d Add debug syslog entries | 16 -d Add debug syslog entries |
17 -e f|t Print the results of looking up from address f and to address | |
18 t in the current config | |
16 | 19 |
17 | 20 |
18 TODO: | 21 TODO: |
19 1) Add config for max_recipients for each mail domain. Recipients in | 22 |
20 excess of that limit will be rejected, and the entire data will be | 23 1) Add option for using smtp connections to verify addresses from backup |
21 rejected if it is sent. | |
22 | |
23 2) Add config for poison addresses. If any recipient is poison, all | |
24 recipients are rejected even if they would be whitelisted, and the | |
25 data is rejected if sent. | |
26 | |
27 3) Add option to only allow one recipient if the return path is empty. | |
28 | |
29 4) Check if the envelope from domain name primary MX points 127.0.0.0/8 | |
30 | |
31 5) Add option for using smtp connections to verify addresses from backup | |
32 mx machines. This allows the backup mx to learn the valid addresses | 24 mx machines. This allows the backup mx to learn the valid addresses |
33 on the primary machine. | 25 on the primary machine. |
34 | 26 |
35 */ | 27 */ |
36 | 28 |
91 | 83 |
92 bool debug_syslog = false; | 84 bool debug_syslog = false; |
93 bool syslog_opened = false; | 85 bool syslog_opened = false; |
94 bool use_syslog = true; // false to printf | 86 bool use_syslog = true; // false to printf |
95 bool loader_run = true; // used to stop the config loader thread | 87 bool loader_run = true; // used to stop the config loader thread |
96 CONFIG * config = NULL; // protected by the config_mutex | 88 CONFIG *config = NULL; // protected by the config_mutex |
97 int generation = 0; // protected by the config_mutex | 89 int generation = 0; // protected by the config_mutex |
90 const int maxlen = 1000; // used for snprintf buffers | |
98 | 91 |
99 pthread_mutex_t config_mutex; | 92 pthread_mutex_t config_mutex; |
100 pthread_mutex_t syslog_mutex; | 93 pthread_mutex_t syslog_mutex; |
101 pthread_mutex_t resolve_mutex; | 94 pthread_mutex_t resolve_mutex; |
102 pthread_mutex_t fd_pool_mutex; | 95 pthread_mutex_t fd_pool_mutex; |
161 void discard(context_map &cm) { | 154 void discard(context_map &cm) { |
162 for (context_map::iterator i=cm.begin(); i!=cm.end(); i++) { | 155 for (context_map::iterator i=cm.begin(); i!=cm.end(); i++) { |
163 char *x = (*i).first; | 156 char *x = (*i).first; |
164 free(x); | 157 free(x); |
165 } | 158 } |
159 cm.clear(); | |
166 } | 160 } |
167 | 161 |
168 | 162 |
169 //////////////////////////////////////////////// | 163 //////////////////////////////////////////////// |
170 // helper to register a string in a context_map | 164 // helper to register a string in a context_map |
233 pthread_mutex_lock(&config_mutex); | 227 pthread_mutex_lock(&config_mutex); |
234 pc = config; | 228 pc = config; |
235 pc->reference_count++; | 229 pc->reference_count++; |
236 pthread_mutex_unlock(&config_mutex); | 230 pthread_mutex_unlock(&config_mutex); |
237 get_fd(); | 231 get_fd(); |
238 ip = 0; | 232 ip = 0; |
239 mailaddr = NULL; | 233 mailaddr = NULL; |
240 queueid = NULL; | 234 queueid = NULL; |
241 authenticated = false; | 235 authenticated = false; |
242 have_whites = false; | 236 have_whites = false; |
243 only_whites = true; | 237 only_whites = true; |
244 memory = new recorder(this, pc->get_html_tags(), pc->get_content_tlds()); | 238 memory = NULL; |
245 scanner = new url_scanner(memory); | 239 scanner = NULL; |
240 content_suffix = NULL; | |
241 content_message = NULL; | |
242 content_host_ignore = NULL; | |
246 } | 243 } |
247 | 244 |
248 mlfiPriv::~mlfiPriv() { | 245 mlfiPriv::~mlfiPriv() { |
249 return_fd(); | 246 return_fd(); |
250 pthread_mutex_lock(&config_mutex); | 247 pthread_mutex_lock(&config_mutex); |
252 pthread_mutex_unlock(&config_mutex); | 249 pthread_mutex_unlock(&config_mutex); |
253 reset(true); | 250 reset(true); |
254 } | 251 } |
255 | 252 |
256 void mlfiPriv::reset(bool final) { | 253 void mlfiPriv::reset(bool final) { |
254 if (debug_syslog) my_syslog(this, "mlfiPriv::reset"); | |
257 if (mailaddr) free(mailaddr); | 255 if (mailaddr) free(mailaddr); |
258 if (queueid) free(queueid); | 256 if (queueid) free(queueid); |
259 discard(env_to); | 257 discard(env_to); |
260 delete memory; | 258 if (memory) delete memory; |
261 delete scanner; | 259 if (scanner) delete scanner; |
262 if (!final) { | 260 if (!final) { |
263 mailaddr = NULL; | 261 mailaddr = NULL; |
264 queueid = NULL; | 262 queueid = NULL; |
265 authenticated = false; | 263 authenticated = false; |
266 have_whites = false; | 264 have_whites = false; |
267 only_whites = true; | 265 only_whites = true; |
268 memory = new recorder(this, pc->get_html_tags(), pc->get_content_tlds()); | 266 memory = NULL; |
269 scanner = new url_scanner(memory); | 267 scanner = NULL; |
270 } | 268 content_suffix = NULL; |
269 content_message = NULL; | |
270 content_host_ignore = NULL; | |
271 } | |
272 if (debug_syslog) my_syslog("mlfiPriv::reset exit"); | |
271 } | 273 } |
272 | 274 |
273 void mlfiPriv::get_fd() { | 275 void mlfiPriv::get_fd() { |
274 err = true; | 276 err = true; |
275 fd = NULL_SOCKET; | 277 fd = NULL_SOCKET; |
366 } | 368 } |
367 return rs; | 369 return rs; |
368 } | 370 } |
369 | 371 |
370 void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) { | 372 void mlfiPriv::need_content_filter(char *rcpt, CONTEXT &con) { |
373 if (debug_syslog) my_syslog(this, "need_content_filter"); | |
371 register_string(env_to, rcpt, &con); | 374 register_string(env_to, rcpt, &con); |
375 if (!memory) { | |
376 // first recipient that needs content filtering sets all | |
377 // the content filtering parameters | |
378 memory = new recorder(this, con.get_html_tags(), con.get_content_tlds()); | |
379 scanner = new url_scanner(memory); | |
380 content_suffix = con.get_content_suffix(); | |
381 content_message = con.get_content_message(); | |
382 content_host_ignore = &con.get_content_host_ignore(); | |
383 } | |
384 if (debug_syslog) my_syslog(this, "need_content_filter exit"); | |
372 } | 385 } |
373 | 386 |
374 #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) | 387 #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) |
375 | 388 |
376 | 389 |
377 //////////////////////////////////////////////// | 390 //////////////////////////////////////////////// |
378 // syslog a message | 391 // syslog a message |
379 // | 392 // |
380 void my_syslog(mlfiPriv *priv, char *text) { | 393 void my_syslog(mlfiPriv *priv, char *text) { |
381 char buf[1000]; | 394 char buf[maxlen]; |
382 if (priv) { | 395 if (priv) { |
383 snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text); | 396 snprintf(buf, sizeof(buf), "%s: %s", priv->queueid, text); |
384 text = buf; | 397 text = buf; |
385 } | 398 } |
386 if (use_syslog) { | 399 if (use_syslog) { |
388 if (!syslog_opened) { | 401 if (!syslog_opened) { |
389 openlog("dnsbl", LOG_PID, LOG_MAIL); | 402 openlog("dnsbl", LOG_PID, LOG_MAIL); |
390 syslog_opened = true; | 403 syslog_opened = true; |
391 } | 404 } |
392 syslog(LOG_NOTICE, "%s", text); | 405 syslog(LOG_NOTICE, "%s", text); |
406 closelog(); | |
407 syslog_opened = false; | |
393 pthread_mutex_unlock(&syslog_mutex); | 408 pthread_mutex_unlock(&syslog_mutex); |
394 } | 409 } |
395 else { | 410 else { |
396 printf("%s \n", text); | 411 printf("%s \n", text); |
397 } | 412 } |
642 // | 657 // |
643 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip); | 658 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip); |
644 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip) { | 659 bool check_hosts(mlfiPriv &priv, bool random, int limit, char *&host, int ip) { |
645 CONFIG &dc = *priv.pc; | 660 CONFIG &dc = *priv.pc; |
646 string_set &hosts = priv.memory->get_hosts(); | 661 string_set &hosts = priv.memory->get_hosts(); |
647 string_set &ignore = dc.get_content_host_ignore(); | 662 string_set &ignore = *priv.content_host_ignore; |
648 char *suffix = dc.get_content_suffix(); | 663 char *suffix = priv.content_suffix; |
649 | 664 |
650 int count = 0; | 665 int count = 0; |
651 int cnt = hosts.size(); // number of hosts we could look at | 666 int cnt = hosts.size(); // number of hosts we could look at |
652 int_set ips; | 667 int_set ips; |
653 ns_map nameservers; | 668 ns_map nameservers; |
660 | 675 |
661 // try to only look at limit/cnt fraction of the available cnt host names in random mode | 676 // try to only look at limit/cnt fraction of the available cnt host names in random mode |
662 if ((cnt > limit) && (limit > 0) && random) { | 677 if ((cnt > limit) && (limit > 0) && random) { |
663 int r = rand() % cnt; | 678 int r = rand() % cnt; |
664 if (r >= limit) { | 679 if (r >= limit) { |
665 char buf[1000]; | 680 char buf[maxlen]; |
666 snprintf(buf, sizeof(buf), "host %s skipped", host); | 681 snprintf(buf, sizeof(buf), "host %s skipped", host); |
667 my_syslog(&priv, buf); | 682 my_syslog(&priv, buf); |
668 continue; | 683 continue; |
669 } | 684 } |
670 } | 685 } |
671 count++; | 686 count++; |
672 ip = dns_interface(priv, host, true, &nameservers); | 687 ip = dns_interface(priv, host, true, &nameservers); |
673 if (debug_syslog) { | 688 if (debug_syslog) { |
674 char buf[1000]; | 689 char buf[maxlen]; |
675 if (ip) { | 690 if (ip) { |
676 char adr[sizeof "255.255.255.255"]; | 691 char adr[sizeof "255.255.255.255"]; |
677 adr[0] = '\0'; | 692 adr[0] = '\0'; |
678 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); | 693 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); |
679 snprintf(buf, sizeof(buf), "host %s found at %s", host, adr); | 694 snprintf(buf, sizeof(buf), "host %s found at %s", host, adr); |
702 } | 717 } |
703 host = (*i).first; // a transient reference that needs to be replaced before we return it | 718 host = (*i).first; // a transient reference that needs to be replaced before we return it |
704 ip = (*i).second; | 719 ip = (*i).second; |
705 if (!ip) ip = dns_interface(priv, host, false, NULL); | 720 if (!ip) ip = dns_interface(priv, host, false, NULL); |
706 if (debug_syslog) { | 721 if (debug_syslog) { |
707 char buf[200]; | 722 char buf[maxlen]; |
708 if (ip) { | 723 if (ip) { |
709 char adr[sizeof "255.255.255.255"]; | 724 char adr[sizeof "255.255.255.255"]; |
710 adr[0] = '\0'; | 725 adr[0] = '\0'; |
711 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); | 726 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); |
712 snprintf(buf, sizeof(buf), "ns %s found at %s", host, adr); | 727 snprintf(buf, sizeof(buf), "ns %s found at %s", host, adr); |
722 ips.insert(ip); | 737 ips.insert(ip); |
723 if (check_single(priv, ip, suffix)) { | 738 if (check_single(priv, ip, suffix)) { |
724 string_map::iterator j = nameservers.ns_host.find(host); | 739 string_map::iterator j = nameservers.ns_host.find(host); |
725 if (j != nameservers.ns_host.end()) { | 740 if (j != nameservers.ns_host.end()) { |
726 char *refer = (*j).second; | 741 char *refer = (*j).second; |
727 char buf[1000]; | 742 char buf[maxlen]; |
728 snprintf(buf, sizeof(buf), "%s with nameserver %s", refer, host); | 743 snprintf(buf, sizeof(buf), "%s with nameserver %s", refer, host); |
729 host = register_string(hosts, buf); // put a copy into hosts, and return that reference | 744 host = register_string(hosts, buf); // put a copy into hosts, and return that reference |
730 } | 745 } |
731 else { | 746 else { |
732 host = register_string(hosts, host); // put a copy into hosts, and return that reference | 747 host = register_string(hosts, host); // put a copy into hosts, and return that reference |
760 //////////////////////////////////////////////// | 775 //////////////////////////////////////////////// |
761 // start of sendmail milter interfaces | 776 // start of sendmail milter interfaces |
762 // | 777 // |
763 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) | 778 sfsistat mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr) |
764 { | 779 { |
780 if (debug_syslog) my_syslog("mlfi_connect"); | |
765 // allocate some private memory | 781 // allocate some private memory |
766 mlfiPriv *priv = new mlfiPriv; | 782 mlfiPriv *priv = new mlfiPriv; |
767 if (hostaddr->sa_family == AF_INET) { | 783 if (hostaddr->sa_family == AF_INET) { |
768 priv->ip = ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr; | 784 priv->ip = ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr; |
769 } | 785 } |
776 } | 792 } |
777 | 793 |
778 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) | 794 sfsistat mlfi_envfrom(SMFICTX *ctx, char **from) |
779 { | 795 { |
780 mlfiPriv &priv = *MLFIPRIV; | 796 mlfiPriv &priv = *MLFIPRIV; |
797 if (debug_syslog) my_syslog(&priv, "mlfi_envfrom"); | |
781 priv.mailaddr = to_lower_string(from[0]); | 798 priv.mailaddr = to_lower_string(from[0]); |
782 priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL); | 799 priv.authenticated = (smfi_getsymval(ctx, "{auth_authen}") != NULL); |
783 return SMFIS_CONTINUE; | 800 return SMFIS_CONTINUE; |
784 } | 801 } |
785 | 802 |
786 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt) | 803 sfsistat mlfi_envrcpt(SMFICTX *ctx, char **rcpt) |
787 { | 804 { |
788 DNSBLP rejectlist = NULL; // list that caused the reject | 805 DNSBLP rejectlist = NULL; // list that caused the reject |
789 mlfiPriv &priv = *MLFIPRIV; | 806 mlfiPriv &priv = *MLFIPRIV; |
807 if (debug_syslog) my_syslog(&priv, "mlfi_envrcpt"); | |
790 CONFIG &dc = *priv.pc; | 808 CONFIG &dc = *priv.pc; |
791 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i")); | 809 if (!priv.queueid) priv.queueid = strdup(smfi_getsymval(ctx, "i")); |
792 char *rcptaddr = rcpt[0]; | 810 char *rcptaddr = rcpt[0]; |
793 char *loto = to_lower_string(rcptaddr); | 811 char *loto = to_lower_string(rcptaddr); |
794 CONTEXT con = *(dc.find_context(loto)->find_context(priv.mailaddr)); | 812 if (debug_syslog) my_syslog(&priv, "finding context"); |
813 CONTEXT &con = *(dc.find_context(loto)->find_context(priv.mailaddr)); | |
814 if (debug_syslog) { | |
815 char buf[maxlen]; | |
816 char msg[maxlen]; | |
817 snprintf(msg, sizeof(msg), "from <%s> to <%s> using context %s", priv.mailaddr, loto, con.get_full_name(buf,maxlen)); | |
818 my_syslog(&priv, msg); | |
819 } | |
820 if (debug_syslog) my_syslog(&priv, "finding from value"); | |
795 char *fromvalue = con.find_from(priv.mailaddr); | 821 char *fromvalue = con.find_from(priv.mailaddr); |
796 free(loto); | 822 free(loto); |
797 status st; | 823 status st; |
798 if (fromvalue == token_black) { | 824 if (fromvalue == token_black) { |
799 st = black; | 825 st = black; |
801 else if (fromvalue == token_white) { | 827 else if (fromvalue == token_white) { |
802 st = white; | 828 st = white; |
803 } | 829 } |
804 else { | 830 else { |
805 // check the dns based lists | 831 // check the dns based lists |
832 if (debug_syslog) my_syslog(&priv, "checking dns lists"); | |
806 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? black : oksofar; | 833 st = (check_dnsbl(priv, con.get_dnsbl_list(), rejectlist)) ? black : oksofar; |
807 } | 834 } |
808 if (st == reject) { | 835 if (st == reject) { |
809 // reject the recipient based on some dnsbl | 836 // reject the recipient based on some dnsbl |
810 char adr[sizeof "255.255.255.255"]; | 837 char adr[sizeof "255.255.255.255"]; |
811 adr[0] = '\0'; | 838 adr[0] = '\0'; |
812 inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr)); | 839 inet_ntop(AF_INET, (const u_char *)&priv.ip, adr, sizeof(adr)); |
813 char buf[2000]; | 840 char buf[maxlen]; |
814 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); | 841 snprintf(buf, sizeof(buf), rejectlist->message, adr, adr); |
815 smfi_setreply(ctx, "550", "5.7.1", buf); | 842 smfi_setreply(ctx, "550", "5.7.1", buf); |
816 return SMFIS_REJECT; | 843 return SMFIS_REJECT; |
817 } | 844 } |
818 else if (st == black) { | 845 else if (st == black) { |
820 smfi_setreply(ctx, "550", "5.7.1", "no such user"); | 847 smfi_setreply(ctx, "550", "5.7.1", "no such user"); |
821 return SMFIS_REJECT; | 848 return SMFIS_REJECT; |
822 } | 849 } |
823 else { | 850 else { |
824 // accept the recipient | 851 // accept the recipient |
852 if (debug_syslog) my_syslog(&priv, "checking content filtering"); | |
825 if (!con.get_content_filtering()) st = white; | 853 if (!con.get_content_filtering()) st = white; |
826 if (st == oksofar) { | 854 if (st == oksofar) { |
827 // but remember the non-whites | 855 // but remember the non-whites |
828 priv.need_content_filter(rcptaddr, con); | 856 priv.need_content_filter(rcptaddr, con); |
829 priv.only_whites = false; | 857 priv.only_whites = false; |
836 } | 864 } |
837 | 865 |
838 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) | 866 sfsistat mlfi_body(SMFICTX *ctx, u_char *data, size_t len) |
839 { | 867 { |
840 mlfiPriv &priv = *MLFIPRIV; | 868 mlfiPriv &priv = *MLFIPRIV; |
869 if (debug_syslog) my_syslog(&priv, "mlfi_body"); | |
841 if (priv.authenticated) return SMFIS_CONTINUE; | 870 if (priv.authenticated) return SMFIS_CONTINUE; |
842 if (priv.only_whites) return SMFIS_CONTINUE; | 871 if (priv.only_whites) return SMFIS_CONTINUE; |
843 priv.scanner->scan(data, len); | 872 priv.scanner->scan(data, len); |
844 return SMFIS_CONTINUE; | 873 return SMFIS_CONTINUE; |
845 } | 874 } |
846 | 875 |
847 sfsistat mlfi_eom(SMFICTX *ctx) | 876 sfsistat mlfi_eom(SMFICTX *ctx) |
848 { | 877 { |
878 if (debug_syslog) my_syslog("mlfi_eom"); | |
849 sfsistat rc; | 879 sfsistat rc; |
850 mlfiPriv &priv = *MLFIPRIV; | 880 mlfiPriv &priv = *MLFIPRIV; |
881 if (debug_syslog) my_syslog(&priv, "mlfi_eom"); | |
851 CONFIG &dc = *priv.pc; | 882 CONFIG &dc = *priv.pc; |
852 char *host = NULL; | 883 char *host = NULL; |
853 int ip; | 884 int ip; |
854 status st; | 885 status st; |
855 // process end of message | 886 // process end of message |
856 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; | 887 if (priv.authenticated || priv.only_whites) rc = SMFIS_CONTINUE; |
857 else { | 888 else { |
889 // assert env_to not empty | |
890 char buf[maxlen]; | |
858 char *msg = NULL; | 891 char *msg = NULL; |
859 string_set alive; | 892 string_set alive; |
860 bool random = false; | 893 bool random = false; |
861 int limit = 0; | 894 int limit = 0; |
862 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) { | 895 for (context_map::iterator i=priv.env_to.begin(); i!=priv.env_to.end(); i++) { |
870 alive.insert(rcpt); | 903 alive.insert(rcpt); |
871 random |= con.get_host_random(); | 904 random |= con.get_host_random(); |
872 limit = max(limit, con.get_host_limit()); | 905 limit = max(limit, con.get_host_limit()); |
873 } | 906 } |
874 } | 907 } |
875 bool rejecting = alive.empty(); | 908 bool rejecting = alive.empty(); // if alive is empty, we must have set msg above in acceptable_content() |
876 if (!rejecting) { | 909 if (!rejecting) { |
877 rejecting = check_hosts(priv, random, limit, host, ip); | 910 if (check_hosts(priv, random, limit, host, ip)) { |
878 if (rejecting) { | |
879 static char buf[2000]; | |
880 char adr[sizeof "255.255.255.255"]; | 911 char adr[sizeof "255.255.255.255"]; |
881 adr[0] = '\0'; | 912 adr[0] = '\0'; |
882 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); | 913 inet_ntop(AF_INET, (const u_char *)&ip, adr, sizeof(adr)); |
883 snprintf(buf, sizeof(buf), dc.get_content_message(), host, adr); | 914 snprintf(buf, sizeof(buf), priv.content_message, host, adr); |
884 msg = buf; | 915 msg = buf; |
916 rejecting = true; | |
885 } | 917 } |
886 } | 918 } |
887 if (!rejecting) { | 919 if (!rejecting) { |
888 rc = SMFIS_CONTINUE; | 920 rc = SMFIS_CONTINUE; |
889 } | 921 } |
890 else if (!priv.have_whites && alive.empty()) { | 922 else if (!priv.have_whites) { |
891 // can reject the entire message | 923 // can reject the entire message |
892 smfi_setreply(ctx, "550", "5.7.1", msg); | 924 smfi_setreply(ctx, "550", "5.7.1", msg); |
893 rc = SMFIS_REJECT; | 925 rc = SMFIS_REJECT; |
894 } | 926 } |
895 else { | 927 else { |
907 } | 939 } |
908 | 940 |
909 sfsistat mlfi_abort(SMFICTX *ctx) | 941 sfsistat mlfi_abort(SMFICTX *ctx) |
910 { | 942 { |
911 mlfiPriv &priv = *MLFIPRIV; | 943 mlfiPriv &priv = *MLFIPRIV; |
944 if (debug_syslog) my_syslog(&priv, "mlfi_abort"); | |
912 priv.reset(); | 945 priv.reset(); |
913 return SMFIS_CONTINUE; | 946 return SMFIS_CONTINUE; |
914 } | 947 } |
915 | 948 |
916 sfsistat mlfi_close(SMFICTX *ctx) | 949 sfsistat mlfi_close(SMFICTX *ctx) |
917 { | 950 { |
918 mlfiPriv *priv = MLFIPRIV; | 951 mlfiPriv *priv = MLFIPRIV; |
952 if (debug_syslog) my_syslog(priv, "mlfi_close"); | |
919 if (!priv) return SMFIS_CONTINUE; | 953 if (!priv) return SMFIS_CONTINUE; |
920 delete priv; | 954 delete priv; |
921 smfi_setpriv(ctx, NULL); | 955 smfi_setpriv(ctx, NULL); |
922 return SMFIS_CONTINUE; | 956 return SMFIS_CONTINUE; |
923 } | 957 } |
947 CONFIG* new_conf() { | 981 CONFIG* new_conf() { |
948 CONFIG *newc = new CONFIG; | 982 CONFIG *newc = new CONFIG; |
949 pthread_mutex_lock(&config_mutex); | 983 pthread_mutex_lock(&config_mutex); |
950 newc->generation = generation++; | 984 newc->generation = generation++; |
951 pthread_mutex_unlock(&config_mutex); | 985 pthread_mutex_unlock(&config_mutex); |
952 char buf[200]; | 986 char buf[maxlen]; |
953 snprintf(buf, sizeof(buf), "loading configuration generation %d", newc->generation); | 987 snprintf(buf, sizeof(buf), "loading configuration generation %d", newc->generation); |
954 my_syslog(buf); | 988 my_syslog(buf); |
955 if (load_conf(*newc, "dnsbl.conf")) { | 989 if (load_conf(*newc, "dnsbl.conf")) { |
956 newc->load_time = time(NULL); | 990 newc->load_time = time(NULL); |
957 return newc; | 991 return newc; |
994 } | 1028 } |
995 // now look for old configs with zero ref counts | 1029 // now look for old configs with zero ref counts |
996 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) { | 1030 for (configp_set::iterator i=old_configs.begin(); i!=old_configs.end(); ) { |
997 CONFIG *old = *i; | 1031 CONFIG *old = *i; |
998 if (!old->reference_count) { | 1032 if (!old->reference_count) { |
999 char buf[200]; | 1033 char buf[maxlen]; |
1000 snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation); | 1034 snprintf(buf, sizeof(buf), "freeing memory for old configuration generation %d", old->generation); |
1001 my_syslog(buf); | 1035 my_syslog(buf); |
1002 delete old; // destructor does all the work | 1036 delete old; // destructor does all the work |
1003 old_configs.erase(i++); | 1037 old_configs.erase(i++); |
1004 } | 1038 } |
1130 exit(EX_USAGE); | 1164 exit(EX_USAGE); |
1131 } | 1165 } |
1132 } | 1166 } |
1133 | 1167 |
1134 if (check) { | 1168 if (check) { |
1135 use_syslog = false; | 1169 use_syslog = false; |
1170 debug_syslog = true; | |
1136 CONFIG *conf = new_conf(); | 1171 CONFIG *conf = new_conf(); |
1137 if (conf) { | 1172 if (conf) { |
1138 conf->dump(); | 1173 conf->dump(); |
1139 delete conf; | 1174 delete conf; |
1140 return 0; | 1175 return 0; |
1165 char *to = strdup(x+1); | 1200 char *to = strdup(x+1); |
1166 use_syslog = false; | 1201 use_syslog = false; |
1167 CONFIG *conf = new_conf(); | 1202 CONFIG *conf = new_conf(); |
1168 if (conf) { | 1203 if (conf) { |
1169 CONTEXTP con = conf->find_context(to); | 1204 CONTEXTP con = conf->find_context(to); |
1170 const int maxlen = 1000; | |
1171 char buf[maxlen]; | 1205 char buf[maxlen]; |
1172 fprintf(stdout, "envelope to <%s> finds context %s\n", to, con->get_full_name(buf,maxlen)); | 1206 fprintf(stdout, "envelope to <%s> finds context %s\n", to, con->get_full_name(buf,maxlen)); |
1173 CONTEXTP fc = con->find_context(from); | 1207 CONTEXTP fc = con->find_context(from); |
1174 fprintf(stdout, "envelope from <%s> finds context %s\n", from, fc->get_full_name(buf,maxlen)); | 1208 fprintf(stdout, "envelope from <%s> finds context %s\n", from, fc->get_full_name(buf,maxlen)); |
1175 char *st = fc->find_from(from); | 1209 char *st = fc->find_from(from); |