Download | Plain Text | No Line Numbers
- diff -Naur qmail-1.03.orig/Makefile qmail-1.03/Makefile
- --- qmail-1.03.orig/Makefile Sun Dec 24 15:24:55 2006
- +++ qmail-1.03/Makefile Mon Dec 25 23:42:18 2006
- @@ -1,5 +1,9 @@
- # Don't edit Makefile! Use conf-* for configuration.
-
- +VPOPMAIL_HOME=/usr/local/vpopmail
- +SMTPD_CHKUSER_OBJ=chkuser.o
- +VPOPMAIL_LIBS=`head -1 $(VPOPMAIL_HOME)/etc/lib_deps`
- +
- SHELL=/bin/sh
-
- default: it
- @@ -312,6 +316,10 @@
- exit.h auto_spawn.h
- ./compile chkspawn.c
-
- +chkuser.o: \
- +compile chkuser.c chkuser.h chkuser_settings.h
- + ./compile chkuser.c
- +
- clean: \
- TARGETS
- rm -f `cat TARGETS`
- @@ -1598,21 +1606,21 @@
- timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o constmap.o \
- received.o date822fmt.o now.o qmail.o spf.o dns.o cdb.a fd.a wait.a \
- datetime.a getln.a open.a sig.a case.a env.a stralloc.a alloc.a substdio.a \
- -error.a str.a fs.a auto_qmail.o base64.o qmail-spp.o socket.lib dns.lib
- - ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
- +error.a str.a fs.a auto_qmail.o base64.o qmail-spp.o socket.lib dns.lib $(SMTPD_CHKUSER_OBJ)
- + ./load qmail-smtpd $(SMTPD_CHKUSER_OBJ) rcpthosts.o commands.o timeoutread.o \
- timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o \
- tls.o ssl_timeoutio.o ndelay.a -L/usr/lib -lssl -lcrypto \
- constmap.o received.o date822fmt.o now.o qmail.o spf.o dns.o cdb.a \
- fd.a wait.a datetime.a getln.a open.a sig.a case.a qmail-spp.o env.a stralloc.a \
- alloc.a substdio.a error.a fs.a auto_qmail.o base64.o \
- - str.a `cat socket.lib` `cat dns.lib`
- + str.a `cat socket.lib` $(VPOPMAIL_LIBS) `cat dns.lib`
-
- qmail-smtpd.0: \
- qmail-smtpd.8
- nroff -man qmail-smtpd.8 > qmail-smtpd.0
-
- qmail-smtpd.o: \
- -compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \
- +compile qmail-smtpd.c chkuser.h sig.h readwrite.h stralloc.h gen_alloc.h \
- substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
- error.h ipme.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ip.h qmail.h qmail-spp.h \
- substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
- diff -Naur qmail-1.03.orig/TARGETS qmail-1.03/TARGETS
- --- qmail-1.03.orig/TARGETS Sun Dec 24 15:24:55 2006
- +++ qmail-1.03/TARGETS Mon Dec 25 23:42:42 2006
- @@ -407,3 +407,4 @@
- man
- setup
- check
- +chkuser.o
- diff -Naur qmail-1.03.orig/chkuser.c qmail-1.03/chkuser.c
- --- qmail-1.03.orig/chkuser.c Thu Jan 1 01:00:00 1970
- +++ qmail-1.03/chkuser.c Mon Dec 25 23:42:27 2006
- @@ -0,0 +1,1156 @@
- +
- +/*
- + *
- + * 'chkuser.c' v.2.0.8
- + * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
- + *
- + * Author: Antonio Nati tonix@interazioni.it
- + * All rights on this software and
- + * the identifying words chkusr and chkuser kept by the author
- + *
- + * This software may be freely used, modified and distributed,
- + * but this lines must be kept in every original or derived version.
- + * Original author "Antonio Nati" and the web URL
- + * "http://www.interazioni.it/opensource"
- + * must be indicated in every related work or web page
- + *
- + */
- +
- +#include <pwd.h>
- +
- +/* required by vpopmail */
- +#include <stdio.h>
- +
- +#include <stdlib.h>
- +#include <string.h>
- +#include <unistd.h>
- +
- +#include "dns.h"
- +#include "env.h"
- +#include "ipme.h"
- +#include "now.h"
- +#include "open.h"
- +#include "subfd.h"
- +#include "substdio.h"
- +#include "stralloc.h"
- +
- +#include "vpopmail.h"
- +#include "vauth.h"
- +#include "vpopmail_config.h"
- +
- +#include "chkuser.h"
- +#include "chkuser_settings.h"
- +
- +#if defined _exit
- +#undef _exit
- +#endif
- +
- +extern void flush();
- +extern void out (char *s);
- +
- +extern char *remotehost;
- +extern char *remoteip;
- +extern char *remoteinfo;
- +extern char *relayclient;
- +extern char *fakehelo;
- +
- +extern void die_nomem();
- +
- +#define DIE_NOMEM() die_nomem()
- +
- +#if defined CHKUSER_DEBUG
- +
- +#if defined CHKUSER_DEBUG_STDERR
- +
- +#define CHKUSER_DBG(a) write (STDERR_FILENO, a, strlen (a))
- +#define CHKUSER_DBG_INT(a) { int x; char str[30]; sprintf (str, "%d", a); write (STDERR_FILENO, str, strlen (str));}
- +
- +#else
- +
- +#define CHKUSER_DBG(a) write (STDOUT_FILENO, a, strlen (a))
- +#define CHKUSER_DBG_INT(a) { int x; char str[30]; sprintf (str, "%d", a); write (STDOUT_FILENO, str, strlen (str));}
- +
- +#endif
- +#else
- +
- +#define CHKUSER_DBG(a) /* DBG dummy */
- +#define CHKUSER_DBG_INT(a) /* DBG dummy */
- +
- +#endif
- +
- +static int INTRUSION_threshold_reached = 0;
- +static int first_time_init_flag = 1;
- +
- +static int recipients = 0;
- +static int wrong_recipients = 0;
- +
- +static stralloc user = {0};
- +static stralloc domain = {0};
- +static stralloc domain_path = {0};
- +static stralloc tmp_path = {0};
- +static stralloc alias_path = {0};
- +
- +#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
- + static char *identify_remote;
- +#endif
- +
- +#if defined CHKUSER_ENABLE_EXTENSIONS
- +#define CHKUSER_ENABLE_USERS_EXTENSIONS
- +#endif
- +
- +#if defined CHKUSER_ENABLE_LISTS
- +#define CHKUSER_ENABLE_EZMLM_LISTS
- +#endif
- +
- +#if defined CHKUSER_EXTENSION_DASH
- +#define CHKUSER_USERS_DASH CHKUSER_EXTENSION_DASH
- +#endif
- +
- +
- +#if defined CHKUSER_ENABLE_VAUTH_OPEN
- + static int db_already_open = 0;
- +#endif
- +
- +#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
- + static char *starting_string = 0;
- + static int starting_value = -1;
- +#endif
- +
- +#if defined CHKUSER_RCPT_LIMIT_VARIABLE
- + static char *maxrcpt_string = 0;
- + static int maxrcpt_limit = 0;
- + static int maxrcpt_limit_reached = 0;
- +#endif
- +
- +#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
- + static char *maxwrongrcpt_string = 0;
- + static int maxwrongrcpt_limit = 0;
- + static int maxwrongrcpt_limit_reached = 0;
- +#endif
- +
- +#if defined CHKUSER_MBXQUOTA_VARIABLE
- + static char *maxmbxquota_string = 0;
- + static int maxmbxquota_limit = 0;
- +#endif
- +
- +#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
- +
- + static unsigned int sender_nocheck = 0;
- +
- +#endif
- +
- +#if defined CHKUSER_SENDER_FORMAT || defined CHKUSER_SENDER_MX
- +static stralloc sender_user = {0};
- +static stralloc sender_domain = {0};
- +#endif
- +
- +
- +#if defined CHKUSER_ERROR_DELAY
- +
- + static int chkuser_delay_interval = CHKUSER_ERROR_DELAY * 1000;
- +
- +#define CHKUSER_DELAY() chkuser_delay()
- +
- +void chkuser_delay (void) {
- +
- + usleep (chkuser_delay_interval);
- +
- +#if defined CHKUSER_ERROR_DELAY_INCREASE
- + chkuser_delay_interval += CHKUSER_ERROR_DELAY_INCREASE * 1000;
- +#endif
- +}
- +
- +#if defined CHKUSER_RCPT_DELAY_ANYERROR
- +#define CHKUSER_RCPT_DELAY_ANY() chkuser_delay()
- +#else
- +#define CHKUSER_RCPT_DELAY_ANY() /* no delay for any error */
- +#endif
- +
- +#if defined CHKUSER_SENDER_DELAY_ANYERROR
- +#define CHKUSER_SENDER_DELAY_ANY() chkuser_delay()
- +#else
- +#define CHKUSER_SENDER_DELAY_ANY() /* no delay for any error */
- +#endif
- +
- +
- +#else
- +#define CHKUSER_DELAY() /* no delay */
- +#define CHKUSER_RCPT_DELAY_ANY() /* no delay */
- +#define CHKUSER_SENDER_DELAY_ANY() /* no delay */
- +#endif
- +
- +#if defined CHKUSER_ENABLE_LOGGING
- +
- +static stralloc logstr = { 0 };
- +
- +static void chkuser_commonlog (char *sender, char *rcpt, char *title, char *description) {
- +
- + substdio_puts (subfderr, "CHKUSER ");
- + substdio_puts (subfderr, title);
- + substdio_puts (subfderr, ": from <");
- + substdio_puts (subfderr, sender);
- + substdio_puts (subfderr, ":" );
- + if (remoteinfo) {
- + substdio_puts (subfderr, remoteinfo);
- + }
- + substdio_puts (subfderr, ":" );
- +#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
- + if (identify_remote) substdio_puts (subfderr, identify_remote);
- +#endif
- + substdio_puts (subfderr, "> remote <");
- + if (fakehelo) substdio_puts (subfderr, fakehelo);
- + substdio_puts (subfderr, ":" );
- + if (remotehost) substdio_puts (subfderr, remotehost);
- + substdio_puts (subfderr, ":" );
- + if (remoteip) substdio_puts (subfderr, remoteip);
- + substdio_puts (subfderr, "> rcpt <");
- + substdio_puts (subfderr, rcpt);
- + substdio_puts (subfderr, "> : ");
- + substdio_puts (subfderr, description);
- + substdio_puts (subfderr, "\n");
- + substdio_flush (subfderr);
- +}
- +
- +#else
- +#define chkuser_commonlog(a,b,c,d) /* no log */
- +#endif
- +
- +#if defined CHKUSER_SENDER_FORMAT
- +
- +static int check_sender_address_format (stralloc *user, stralloc *domain) {
- +
- + int x;
- +
- + for (x = 0; x < (user->len -1); ++x) {
- + if ((!isalnum (user->s[x]))
- +
- +#if defined CHKUSER_ALLOW_SENDER_SRS
- + && (user->s[x] != '#')
- + && (user->s[x] != '+')
- +#endif
- +#if defined CHKUSER_ALLOW_SENDER_CHAR_1
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_1)
- +#endif
- +#if defined CHKUSER_ALLOW_SENDER_CHAR_2
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_2)
- +#endif
- +#if defined CHKUSER_ALLOW_SENDER_CHAR_3
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_3)
- +#endif
- +#if defined CHKUSER_ALLOW_SENDER_CHAR_4
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_4)
- +#endif
- +#if defined CHKUSER_ALLOW_SENDER_CHAR_5
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_5)
- +#endif
- + && (user->s[x] != '_') && (user->s[x] != '-') && (user->s[x] != '.') && (user->s[x] != '=')) {
- + return 0;
- + }
- + }
- +
- +/*
- + * Be careful, this is a base check
- + * Minimum is x.xx + ending \0
- + * Minimum characters needed are 5
- + */
- +#if defined CHKUSER_MIN_DOMAIN_LEN
- + if (domain->len < (CHKUSER_MIN_DOMAIN_LEN +1)) {
- + return 0;
- + }
- +#endif
- +
- +/*
- + * This is a safety check
- + */
- +#if defined CHKUSER_MIN_DOMAIN_LEN
- + if (domain->len < 2) {
- + return 0;
- + }
- +#endif
- +
- + for (x = 0; x < (domain->len -1); ++x) {
- + if ((!isalnum (domain->s[x])) && (domain->s[x] != '-') && (domain->s[x] != '.')) {
- + return 0;
- + }
- + }
- +
- + if ((domain->s[0] == '-') || (domain->s[domain->len -2] == '-') || (domain->s[0] == '.') || (domain->s[domain->len -2] == '.')) {
- + return 0;
- + }
- + if (strstr (domain->s, "..") != NULL) {
- + return 0;
- + }
- + if (strncmp (domain->s, "xn--", 4) == 0) {
- + if (strstr (&domain->s[4], "--") != NULL)
- + return 0;
- + } else {
- + if (strstr (domain->s, "--") != NULL)
- + return 0;
- + }
- + if (strstr (domain->s, ".-") != NULL) {
- + return 0;
- + }
- + if (strstr (domain->s, "-.") != NULL) {
- + return 0;
- + }
- + if (strchr (domain->s, '.') == NULL) {
- + return 0;
- + }
- +
- + return 1;
- +}
- +
- +#endif
- +
- +#if defined CHKUSER_RCPT_FORMAT
- +
- +static int check_rcpt_address_format (stralloc *user, stralloc *domain) {
- +
- + int x;
- +
- + for (x = 0; x < (user->len -1); ++x) {
- + if ((!isalnum (user->s[x]))
- +#if defined CHKUSER_ALLOW_RCPT_SRS
- + && (user->s[x] != '#')
- + && (user->s[x] != '+')
- +#endif
- +#if defined CHKUSER_ALLOW_RCPT_CHAR_1
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_1)
- +#endif
- +#if defined CHKUSER_ALLOW_RCPT_CHAR_2
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_2)
- +#endif
- +#if defined CHKUSER_ALLOW_RCPT_CHAR_3
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_3)
- +#endif
- +#if defined CHKUSER_ALLOW_RCPT_CHAR_4
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_4)
- +#endif
- +#if defined CHKUSER_ALLOW_RCPT_CHAR_5
- + && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_5)
- +#endif
- +
- + && (user->s[x] != '_') && (user->s[x] != '-') && (user->s[x] != '.') && (user->s[x] != '=')) {
- + return 0;
- + }
- + }
- +
- +/*
- + * Be careful, this is a base check
- + * Minimum is x.xx + ending \0
- + * Minimum characters needed are 5
- + */
- +#if defined CHKUSER_MIN_DOMAIN_LEN
- + if (domain->len < (CHKUSER_MIN_DOMAIN_LEN +1)) {
- + return 0;
- + }
- +#endif
- +
- +/*
- + * This is a safety check
- + */
- +#if defined CHKUSER_MIN_DOMAIN_LEN
- + if (domain->len < 2) {
- + return 0;
- + }
- +#endif
- + for (x = 0; x < (domain->len -1); ++x) {
- + if ((!isalnum (domain->s[x])) && (domain->s[x] != '-') && (domain->s[x] != '.')) {
- + return 0;
- + }
- + }
- +
- + if ((domain->s[0] == '-') || (domain->s[domain->len -2] == '-') || (domain->s[0] == '.') || (domain->s[domain->len -2] == '.')) {
- + return 0;
- + }
- + if (strstr (domain->s, "..") != NULL) {
- + return 0;
- + }
- + if (strncmp (domain->s, "xn--", 4) == 0) {
- + if (strstr (&domain->s[4], "--") != NULL)
- + return 0;
- + } else {
- + if (strstr (domain->s, "--") != NULL)
- + return 0;
- + }
- + if (strstr (domain->s, ".-") != NULL) {
- + return 0;
- + }
- + if (strstr (domain->s, "-.") != NULL) {
- + return 0;
- + }
- + if (strchr (domain->s, '.') == NULL) {
- + return 0;
- + }
- +
- + return 1;
- +}
- +
- +#endif
- +
- +#if defined CHKUSER_SENDER_MX || defined CHKUSER_RCPT_MX
- +
- +static unsigned long mx_random;
- +static ipalloc mx_ip = {0};
- +
- +static int chkuser_mx_lookup (stralloc *domain) {
- +
- + int status;
- +
- + mx_random = now() + getpid();
- + dns_init(0);
- + status = dns_mxip (&mx_ip, domain, mx_random);
- +
- + if (status == DNS_MEM) DIE_NOMEM();
- +
- + return status;
- +}
- +
- +#endif
- +
- +
- +void chkuser_cleanup (int exit_value) {
- +
- +#if defined CHKUSER_DB_CLEANUP
- + vclose ();
- +#endif
- + _exit (exit_value);
- +}
- +
- +static void first_time_init (void) {
- +
- + char * temp_string;
- +
- +#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
- + starting_string = env_get (CHKUSER_STARTING_VARIABLE);
- + if (starting_string) {
- + if (strcasecmp(starting_string, "ALWAYS") == 0) {
- + starting_value = 1;
- + } else if (strcasecmp(starting_string, "DOMAIN") == 0) {
- + starting_value = 0;
- + }
- + } else {
- + starting_string = "";
- + }
- +#endif
- +
- +#if defined CHKUSER_RCPT_LIMIT_VARIABLE
- + maxrcpt_string = env_get (CHKUSER_RCPT_LIMIT_VARIABLE);
- + if (maxrcpt_string) {
- + maxrcpt_limit = atoi (maxrcpt_string);
- + if (maxrcpt_limit < 1) {
- + maxrcpt_limit = 0;
- + }
- + } else {
- + maxrcpt_string = "";;
- + }
- +#endif
- +
- +#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
- + maxwrongrcpt_string = env_get (CHKUSER_WRONGRCPT_LIMIT_VARIABLE);
- + if (maxwrongrcpt_string) {
- + maxwrongrcpt_limit = atoi (maxwrongrcpt_string);
- + if (maxwrongrcpt_limit < 1) {
- + maxwrongrcpt_limit = 0;
- + }
- + } else {
- + maxwrongrcpt_string = "";
- + }
- +#endif
- +
- +#if defined CHKUSER_MBXQUOTA_VARIABLE
- + maxmbxquota_string = env_get (CHKUSER_MBXQUOTA_VARIABLE);
- + if (maxmbxquota_string) {
- + maxmbxquota_limit = atoi (maxmbxquota_string);
- + if (maxmbxquota_limit < 1) {
- + maxmbxquota_limit = 0;
- + }
- + } else {
- + maxmbxquota_string = "";
- + }
- +#endif
- +
- +#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
- +
- + temp_string = env_get (CHKUSER_SENDER_NOCHECK_VARIABLE);
- + if (temp_string) {
- + sender_nocheck = 1;
- + } else {
- + sender_nocheck = 0;
- + }
- +
- +#endif
- +
- +#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
- +
- + identify_remote = env_get (CHKUSER_IDENTIFY_REMOTE_VARIABLE);
- + if (identify_remote) {
- + }
- +
- +#endif
- +
- + if (!stralloc_ready (&user, 300)) DIE_NOMEM();
- + if (!stralloc_ready (&domain, 500)) DIE_NOMEM();
- + if (!stralloc_ready (&domain_path, 1000)) DIE_NOMEM();
- + if (!stralloc_ready (&tmp_path, 1000)) DIE_NOMEM();
- + if (!stralloc_ready (&alias_path, 1000)) DIE_NOMEM();
- +
- + first_time_init_flag = 0;
- +
- +}
- +
- +/*
- + * realrcpt ()
- + *
- + * Returns:
- + *
- + * CHKUSER_OK = 1 = Ok, recipients does exists
- + *
- + * 0 = Not in rcpthosts
- + *
- + * < 0 various errors
- + *
- + *
- + * Parameters:
- + * stralloc *sender = sender address
- + * stralloc *rcpt = rcpt address to check
- + *
- + *
- +*/
- +
- +static int realrcpt (stralloc *sender, stralloc *rcpt)
- +{
- + int count;
- + int retstat = CHKUSER_KO;
- + struct vqpasswd *user_passwd = NULL;
- + int fd_file = -1;
- + int read_char;
- + int offset;
- + char read_buf[1024];
- +
- +#if defined CHKUSER_ENABLE_UIDGID
- + uid_t eff_uid;
- + gid_t eff_gid;
- +#endif
- +
- +#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
- + if (starting_value == -1) {
- + if (addrallowed()) {
- + return CHKUSER_OK;
- + } else {
- + if (relayclient) {
- + return CHKUSER_RELAYING;
- + }
- +
- + return CHKUSER_NORCPTHOSTS;
- + }
- + }
- +#endif
- +
- + if (INTRUSION_threshold_reached == 1) {
- + return CHKUSER_ERR_INTRUSION_THRESHOLD;
- + }
- +
- +#if defined CHKUSER_RCPT_LIMIT_VARIABLE
- +
- + ++recipients;
- + if ((maxrcpt_limit > 0) && (recipients >= maxrcpt_limit)) {
- + chkuser_commonlog (sender->s, rcpt->s, "intrusion threshold", "max number of allowed rcpt");
- + INTRUSION_threshold_reached = 1;
- + return CHKUSER_ERR_MAXRCPT;
- + }
- +#endif
- +
- +/* Search the '@' character */
- + count = byte_rchr(rcpt->s,rcpt->len,'@');
- +
- + if (count < rcpt->len) {
- + if (!stralloc_copyb (&user, rcpt->s, count)) DIE_NOMEM();
- + if (!stralloc_copys (&domain, rcpt->s + count + 1)) DIE_NOMEM();
- + }
- + else {
- + if (!stralloc_copys (&user, rcpt->s)) DIE_NOMEM();
- + domain.len = 0;
- + }
- + if (!stralloc_0 (&user)) DIE_NOMEM();
- + if (!stralloc_0 (&domain)) DIE_NOMEM();
- +
- +#if defined CHKUSER_ENABLE_UIDGID
- +
- +/* qmail-smtpd is running now as (effective) qmaild:nofiles */
- +/* Save the effective UID & GID (qmaild:nofiles) */
- + eff_uid = geteuid ();
- + eff_gid = getegid ();
- +
- +/* Now set new effective UID & GID, getting it from real UID & GID (vpopmail:vchkpw) */
- + setegid (getgid());
- + seteuid (getuid());
- +
- +/* qmail-smtpd is running now as effective vpopmail:vchkpw */
- +#endif
- +
- +
- +/*
- + *
- + * Now let's start the test/setting suite
- + *
- + **/
- +
- + switch (0) {
- +
- + case 0:
- +/* These are some preliminary settings */
- + case_lowers (user.s);
- + case_lowers (domain.s);
- +
- + case 1:
- +
- + if (domain.len == 1) {
- +#if defined CHKUSER_DOMAIN_WANTED
- + retstat = CHKUSER_ERR_DOMAIN_MISSING;
- + break;
- +#else
- + if (!stralloc_copys (&domain, DEFAULT_DOMAIN)) DIE_NOMEM();
- + if (!stralloc_0 (&domain)) DIE_NOMEM();
- +#endif
- + }
- +
- + case 2:
- +
- +#if defined CHKUSER_RCPT_FORMAT
- +
- + if (check_rcpt_address_format (&user, &domain) == 0) {
- + retstat = CHKUSER_ERR_RCPT_FORMAT;
- + break;
- + }
- +#endif
- +
- + case 3:
- +
- + if (!addrallowed()) {
- +
- +#if defined CHKUSER_RCPT_MX
- + switch (chkuser_mx_lookup(&domain)) {
- +
- + case DNS_HARD:
- + retstat = CHKUSER_ERR_RCPT_MX;
- + break;
- +
- + case DNS_SOFT:
- + retstat = CHKUSER_ERR_RCPT_MX_TMP;
- + break;
- + }
- +
- + if (retstat != CHKUSER_KO) {
- + break;
- + }
- +#endif
- +
- + if (relayclient) {
- + retstat = CHKUSER_RELAYING;
- + break;
- + }
- +
- + retstat = CHKUSER_NORCPTHOSTS;
- + break;
- + }
- +
- + case 4:
- +
- +#if defined CHKUSER_ENABLE_VAUTH_OPEN
- + if (db_already_open != 1) {
- + if (vauth_open () == 0) {
- + db_already_open == 1;
- + } else {
- + retstat = CHKUSER_ERR_AUTH_RESOURCE;
- + }
- + };
- +#endif
- +
- + case 5:
- +
- +#if defined CHKUSER_ENABLE_VGET_REAL_DOMAIN
- +/* Check if domain is a real domain */
- +
- + vget_real_domain(domain.s, domain.a);
- +
- + domain.len = strlen (domain.s) +1;
- + if (domain.len > (domain.a - 1)) DIE_NOMEM();
- +#endif
- +
- +/* Let's get domain's real path */
- + if (vget_assign(domain.s, domain_path.s, domain_path.a -1, NULL, NULL) == NULL) {
- + retstat = CHKUSER_OK;
- + break;
- + }
- +
- + domain_path.len = strlen (domain_path.s);
- +
- + case 6:
- +
- +/* Check if domain has bouncing enabled */
- +
- +#if !defined CHKUSER_ALWAYS_ON
- +
- +#if defined CHKUSER_STARTING_VARIABLE
- + if (starting_value == 0) {
- +#endif
- +
- + if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
- +
- +#if defined CHKUSER_SPECIFIC_BOUNCING
- + if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
- + if (!stralloc_cats (&tmp_path, CHKUSER_SPECIFIC_BOUNCING)) DIE_NOMEM();
- + if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
- + fd_file = open_read (tmp_path.s);
- + if (fd_file != -1) {
- + close (fd_file);
- + } else {
- + retstat = CHKUSER_OK;
- + break;
- + }
- +#else
- + if (!stralloc_cats (&tmp_path, "/.qmail-default")) DIE_NOMEM();
- + if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
- +
- + read_char = 0;
- + fd_file = open_read (tmp_path.s);
- + if (fd_file != -1) {
- + read_char = read (fd_file, read_buf, sizeof(read_buf) - 1);
- + close (fd_file);
- + if (read_char < 0) read_char = 0;
- + }
- + read_buf[read_char] = 0;
- +
- + if ( strstr(read_buf, CHKUSER_BOUNCE_STRING) == NULL ) {
- + retstat = CHKUSER_OK;
- + break;
- + }
- +#endif
- +#if defined CHKUSER_STARTING_VARIABLE
- + }
- +#endif
- +#endif
- +
- + case 7:
- +#if defined VALIAS
- +/* Check for aliases/forwards - valias*/
- +
- + if (valias_select (user.s, domain.s) != NULL) {
- + retstat = CHKUSER_OK;
- + break;
- + }
- +#endif
- +
- + case 8:
- +#if defined CHKUSER_ENABLE_ALIAS
- +/* Check for aliases/forwards - .qmail.x files */
- +
- + if (!stralloc_copy (&tmp_path, &user)) DIE_NOMEM();
- + /* Change all '.' in ':' before continuing on aliases */
- + for (count = 0; count < tmp_path.len; ++count)
- + if (*(tmp_path.s + count) == '.') *(tmp_path.s + count) = ':';
- +
- + if (!stralloc_copy (&alias_path, &domain_path)) DIE_NOMEM();
- + if (!stralloc_cats (&alias_path, "/.qmail-")) DIE_NOMEM();
- + if (!stralloc_cats (&alias_path, tmp_path.s)) DIE_NOMEM();
- + if (!stralloc_0 (&alias_path)) DIE_NOMEM();
- +
- + fd_file = open_read (alias_path.s);
- + if (fd_file != -1) {
- + close (fd_file);
- + retstat = CHKUSER_OK;
- + break;
- + }
- +#endif
- +
- + case 9:
- +
- +#if defined CHKUSER_ENABLE_ALIAS_DEFAULT
- +
- + if (!stralloc_copy (&tmp_path, &user)) DIE_NOMEM();
- + /* Change all '.' in ':' before continuing on aliases */
- + for (count = 0; count < tmp_path.len; ++count)
- + if (*(tmp_path.s + count) == '.') *(tmp_path.s + count) = ':';
- +
- + /* Search for the outer '-' character */
- + for (offset = user.len - 1; offset > 0; --offset)
- + if (*(user.s + offset) == CHKUSER_USERS_DASH) {
- + if (!stralloc_copy (&alias_path, &domain_path)) die_nomem();
- + if (!stralloc_cats (&alias_path, "/.qmail-")) die_nomem();
- + if (!stralloc_catb (&alias_path, user.s, offset)) die_nomem();
- + if (!stralloc_cats (&alias_path, "-default")) die_nomem();
- + if (!stralloc_0 (&alias_path)) die_nomem();
- +
- + fd_file = open_read (alias_path.s);
- + if (fd_file != -1) {
- + close (fd_file);
- + retstat = CHKUSER_OK;
- + break;
- + }
- + }
- +
- + if (retstat != CHKUSER_KO) {
- + break;
- + }
- +
- +#endif
- +
- + case 10:
- +#if defined CHKUSER_ENABLE_USERS
- +/* User control: check the existance of a real user */
- +
- + user_passwd = vauth_getpw (user.s, domain.s);
- +
- +#if defined CHKUSER_ENABLE_USERS_EXTENSIONS
- + if (user_passwd == NULL) {
- + count = 0;
- + while ((count < (user.len -1)) && (user_passwd == NULL)) {
- + count += byte_chr(&user.s[count], user.len - count, CHKUSER_USERS_DASH);
- + if (count < user.len) {
- + if (!stralloc_copyb (&tmp_path, user.s, count)) DIE_NOMEM();
- + if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
- + user_passwd = vauth_getpw (tmp_path.s, domain.s);
- + ++count;
- + }
- + }
- + }
- +
- +#endif
- + if (user_passwd != NULL) {
- +
- + /* If user exists check if he has BOUNCE_MAIL flag set */
- +
- + if (user_passwd->pw_gid & BOUNCE_MAIL)
- + retstat = CHKUSER_KO;
- + else {
- + retstat = CHKUSER_OK;
- +#if defined CHKUSER_MBXQUOTA_VARIABLE
- + if ((maxmbxquota_limit > 0) && (strcasecmp(user_passwd->pw_shell, "NOQUOTA") != 0)) {
- + if (!stralloc_copys (&tmp_path, user_passwd->pw_dir)) DIE_NOMEM();
- + if (!stralloc_cats (&tmp_path, "/Maildir")) DIE_NOMEM();
- + if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
- +
- + if (vmaildir_readquota(tmp_path.s,format_maildirquota(user_passwd->pw_shell))
- + >= maxmbxquota_limit) {
- + retstat = CHKUSER_ERR_MBXFULL;
- + }
- + }
- +#endif
- + }
- + break;
- + }
- +#endif
- +
- + case 11:
- +#if defined CHKUSER_ENABLE_EZMLM_LISTS
- +/* Let's check for mailing lists */
- +
- + /* Search for the outer CHKUSER_EZMLM_DASH character */
- + for (offset = user.len - 2; offset > 0; --offset) {
- + if (*(user.s + offset) == CHKUSER_EZMLM_DASH) {
- + if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
- + if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
- + if (!stralloc_catb (&tmp_path, user.s, offset)) DIE_NOMEM();
- + if (!stralloc_cats (&tmp_path, "/mailinglist")) DIE_NOMEM();
- + if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
- + fd_file = open_read (tmp_path.s);
- + if (fd_file != -1) {
- + close (fd_file);
- + retstat = CHKUSER_OK;
- + break;
- + }
- + }
- + }
- + if (retstat != CHKUSER_KO) {
- + break;
- + }
- +#endif
- +
- + case 12:
- +#if defined CHKUSER_ENABLE_MAILMAN_LISTS
- +/* Let's check for mailing lists */
- +
- + /* Search for the outer CHKUSER_MAILMAN_DASH character */
- + for (offset = user.len - 2; offset > 0; --offset) {
- + if (*(user.s + offset) == CHKUSER_MAILMAN_DASH) {
- + if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
- + if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
- + if (!stralloc_cats (&alias_path, "/.qmail-")) DIE_NOMEM();
- + if (!stralloc_catb (&tmp_path, user.s, offset)) DIE_NOMEM();
- + if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
- + fd_file = open_read (tmp_path.s);
- + read_char = 0;
- + if (fd_file != -1) {
- + read_char = read (fd_file, read_buf, sizeof(read_buf) - 1);
- + close (fd_file);
- + if (read_char < 0) read_char = 0;
- + }
- + read_buf[read_char] = 0;
- +
- + if ( strstr(read_buf, CHKUSER_MAILMAN_STRING) == NULL ) {
- + retstat = CHKUSER_OK;
- + break;
- + }
- +
- + }
- + }
- + if (retstat != CHKUSER_KO) {
- + break;
- + }
- +#endif
- +
- +/*
- + * Add this code if another case is following
- + case xx:
- + code ....
- + code ....
- + code ....
- + code ....
- +
- + if (xxxxxxxx) {
- + retstat != CHKUSER_KO)
- + break;
- + }
- +*/
- +
- + default:
- + retstat = CHKUSER_KO;
- +
- + } /* end switch */
- +
- +#if defined CHKUSER_ENABLE_UIDGID
- +/* Now switch back effective to saved UID & GID (qmaild:nofiles) */
- +
- + setegid (eff_gid);
- + seteuid (eff_uid);
- +
- +/* qmail-smtpd is running again as (effective) qmaild:nofiles */
- +#endif
- +
- + return retstat;
- +
- +}
- +
- +
- +
- +/*
- + * chkuser_realrcpt ()
- + *
- + * Returns a simple status:
- + *
- + * CHKUSER_OK = 1 = Ok, recipients does exists
- + *
- + * CHKUSER_NORCPTHOSTS = Not in rcpthosts
- + *
- + * CHKUSER_KO = ERROR
- + *
- + *
- + * Parameters:
- + * stralloc *sender = sender address
- + * stralloc *rcpt = rcpt address to check
- + *
- + *
- +*/
- +
- +int chkuser_realrcpt (stralloc *sender, stralloc *rcpt) {
- +
- +int retstat;
- +
- + if (first_time_init_flag) {
- + first_time_init ();
- + }
- +
- + retstat = realrcpt (sender, rcpt);
- +
- + switch (retstat) {
- +
- + case CHKUSER_OK:
- +#if defined CHKUSER_LOG_VALID_RCPT
- + chkuser_commonlog (sender->s, rcpt->s, "accepted rcpt", "found existing recipient");
- +#endif
- + return CHKUSER_OK;
- + break;
- +
- + case CHKUSER_RELAYING:
- +#if defined CHKUSER_LOG_VALID_RCPT
- + chkuser_commonlog (sender->s, rcpt->s, "relaying rcpt", "client allowed to relay");
- +#endif
- + return CHKUSER_RELAYING;
- + break;
- +
- + case CHKUSER_NORCPTHOSTS:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected relaying", "client not allowed to relay");
- + CHKUSER_RCPT_DELAY_ANY();
- + out(CHKUSER_NORELAY_STRING);
- + break;
- +
- + case CHKUSER_KO:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "not existing recipient");
- + CHKUSER_DELAY();
- + out(CHKUSER_NORCPT_STRING);
- + break;
- +
- + case CHKUSER_ERR_AUTH_RESOURCE:
- + chkuser_commonlog (sender->s, rcpt->s, "no auth resource", "no auth resource available");
- + CHKUSER_RCPT_DELAY_ANY();
- + out(CHKUSER_RESOURCE_STRING);
- + break;
- +
- + case CHKUSER_ERR_MBXFULL:
- + chkuser_commonlog (sender->s, rcpt->s, "mbx overquota", "rcpt mailbox is overquota");
- + CHKUSER_RCPT_DELAY_ANY();
- + out(CHKUSER_MBXFULL_STRING);
- + break;
- +
- + case CHKUSER_ERR_MAXRCPT:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "max number of recipients");
- + CHKUSER_DELAY ();
- + out(CHKUSER_MAXRCPT_STRING);
- + break;
- +
- + case CHKUSER_ERR_MAXWRONGRCPT:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "max number of invalid recipients");
- + CHKUSER_DELAY ();
- + out(CHKUSER_MAXWRONGRCPT_STRING);
- + break;
- +
- + case CHKUSER_ERR_INTRUSION_THRESHOLD:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected intrusion", "rcpt ignored, session over INTRUSION threshold");
- + CHKUSER_DELAY ();
- + out(CHKUSER_INTRUSIONTHRESHOLD_STRING);
- + break;
- +
- + case CHKUSER_ERR_DOMAIN_MISSING:
- + CHKUSER_DELAY ();
- + out(CHKUSER_DOMAINMISSING_STRING);
- + break;
- +
- + case CHKUSER_ERR_RCPT_FORMAT:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "invalid rcpt address format");
- + CHKUSER_RCPT_DELAY_ANY();
- + out(CHKUSER_RCPTFORMAT_STRING);
- + break;
- +
- + case CHKUSER_ERR_RCPT_MX:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "invalid rcpt MX domain");
- + CHKUSER_RCPT_DELAY_ANY();
- + out(CHKUSER_RCPTMX_STRING);
- + break;
- +
- + case CHKUSER_ERR_RCPT_MX_TMP:
- + chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "temporary DNS problem");
- + CHKUSER_RCPT_DELAY_ANY();
- + out(CHKUSER_RCPTMX_TMP_STRING);
- + break;
- + }
- +
- +
- +
- +#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
- + if ((retstat == CHKUSER_KO) || (retstat == CHKUSER_ERR_DOMAIN_MISSING)) {
- + ++wrong_recipients;
- + if ((INTRUSION_threshold_reached == 0) && (maxwrongrcpt_limit > 0) && (wrong_recipients >= maxwrongrcpt_limit)) {
- + chkuser_commonlog (sender->s, rcpt->s, "intrusion threshold", "max number of allowed invalid rcpt");
- + INTRUSION_threshold_reached = 1;
- + }
- + }
- +#endif
- +
- + return CHKUSER_KO;
- +}
- +
- +
- +/*
- + *
- + * This routine checks for sender format and MX
- + *
- + */
- +
- +
- +int chkuser_sender (stralloc *sender) {
- +
- +int count;
- +
- + if (first_time_init_flag) {
- + first_time_init ();
- + }
- +
- +#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
- + if (starting_value == -1) {
- + return CHKUSER_OK;
- + }
- +#endif
- +
- +#if defined CHKUSER_SENDER_FORMAT || defined CHKUSER_SENDER_MX
- +
- +#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
- +
- + if (sender_nocheck == 1) {
- + return CHKUSER_OK;
- + }
- +#endif
- +
- + if (sender->len <= 1) {
- +#if defined CHKUSER_LOG_VALID_SENDER
- + chkuser_commonlog (sender->s, "", "accepted null sender", "accepted null sender always");
- +#endif
- + return CHKUSER_OK;
- + }
- +
- + count = byte_rchr(sender->s,sender->len,'@');
- + if (count < sender->len) {
- + if (!stralloc_copyb (&sender_user, sender->s, count)) DIE_NOMEM();
- + if (!stralloc_copys (&sender_domain, sender->s + count + 1)) DIE_NOMEM();
- + } else {
- + if (!stralloc_copys (&sender_user, sender->s)) DIE_NOMEM();
- + sender_domain.len = 0;
- + }
- + if (!stralloc_0 (&sender_user)) DIE_NOMEM();
- + if (!stralloc_0 (&sender_domain)) DIE_NOMEM();
- +
- +#if defined CHKUSER_SENDER_FORMAT
- + if (check_sender_address_format (&sender_user, &sender_domain) == 0) {
- + chkuser_commonlog (sender->s, "", "rejected sender", "invalid sender address format");
- + CHKUSER_SENDER_DELAY_ANY();
- + out(CHKUSER_SENDERFORMAT_STRING);
- + return CHKUSER_ERR_SENDER_FORMAT;
- + }
- +
- +#endif
- +
- +#if defined CHKUSER_SENDER_MX
- +
- + switch (chkuser_mx_lookup(&sender_domain)) {
- +
- + case DNS_HARD:
- + CHKUSER_SENDER_DELAY_ANY();
- + out(CHKUSER_SENDERMX_STRING);
- + chkuser_commonlog (sender->s, "", "rejected sender", "invalid sender MX domain");
- + return CHKUSER_ERR_SENDER_MX;
- + break;
- +
- + case DNS_SOFT:
- + CHKUSER_SENDER_DELAY_ANY();
- + out(CHKUSER_SENDERMX_TMP_STRING);
- + chkuser_commonlog (sender->s, "", "rejected sender", "temporary DNS problem");
- + return CHKUSER_ERR_SENDER_MX_TMP;
- + break;
- + }
- +
- +#if defined CHKUSER_LOG_VALID_SENDER
- + chkuser_commonlog (sender->s, "", "accepted sender", "sender accepted");
- +#endif
- +
- + return CHKUSER_OK;
- +#endif
- +
- +#else
- +
- + return CHKUSER_OK;
- +
- +#endif
- +
- +}
- +
- +
- diff -Naur qmail-1.03.orig/chkuser.h qmail-1.03/chkuser.h
- --- qmail-1.03.orig/chkuser.h Thu Jan 1 01:00:00 1970
- +++ qmail-1.03/chkuser.h Mon Dec 25 23:42:27 2006
- @@ -0,0 +1,51 @@
- +
- +/*
- + *
- + * 'chkuser.h' v.2.0.8
- + * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
- + *
- + * Author: Antonio Nati tonix@interazioni.it
- + * All rights on this software and
- + * the identifying words chkusr and chkuser kept by the author
- + *
- + * This software may be freely used, modified and distributed,
- + * but this lines must be kept in every original or derived version.
- + * Original author "Antonio Nati" and the web URL
- + * "http://www.interazioni.it/opensource"
- + * must be indicated in every related work or web page
- + *
- + */
- +
- +#define CHKUSER
- +#define CHKUSER_VERSION "2.0.8"
- +#define CHKUSER_VERSION_RL 2
- +#define CHKUSER_VERSION_MJ 0
- +#define CHKUSER_VERSION_MN 8
- +
- +#define CHKUSER_OK 1
- +#define CHKUSER_RELAYING 0
- +#define CHKUSER_KO -1
- +#define CHKUSER_NORCPTHOSTS -10
- +#define CHKUSER_ERR_AUTH_RESOURCE -20
- +#define CHKUSER_ERR_MBXFULL -30
- +#define CHKUSER_ERR_MAXRCPT -40
- +#define CHKUSER_ERR_MAXWRONGRCPT -50
- +#define CHKUSER_ERR_DOMAIN_MISSING -60
- +#define CHKUSER_ERR_RCPT_FORMAT -70
- +#define CHKUSER_ERR_RCPT_MX -75
- +#define CHKUSER_ERR_RCPT_MX_TMP -76
- +#define CHKUSER_ERR_SENDER_FORMAT -80
- +#define CHKUSER_ERR_SENDER_MX -85
- +#define CHKUSER_ERR_SENDER_MX_TMP -86
- +#define CHKUSER_ERR_INTRUSION_THRESHOLD -90
- +
- +void chkuser_cleanup (int exit_value);
- +int chkuser_realrcpt (stralloc *sender, stralloc *rcpt);
- +int chkuser_sender (stralloc *sender);
- +
- +#ifdef TLS_H
- +#undef _exit
- +#define _exit(value) { if (ssl) ssl_free(ssl); chkuser_cleanup(value); }
- +#else
- +#define _exit(value) chkuser_cleanup(value);
- +#endif
- diff -Naur qmail-1.03.orig/chkuser_settings.h qmail-1.03/chkuser_settings.h
- --- qmail-1.03.orig/chkuser_settings.h Thu Jan 1 01:00:00 1970
- +++ qmail-1.03/chkuser_settings.h Mon Dec 25 23:42:27 2006
- @@ -0,0 +1,373 @@
- +
- +/*
- + *
- + * 'chkuser_settings.h' v.2.0.8
- + * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
- + *
- + * Author: Antonio Nati tonix@interazioni.it
- + * All rights on this software and
- + * the identifying words chkusr and chkuser kept by the author
- + *
- + * This software may be freely used, modified and distributed,
- + * but this lines must be kept in every original or derived version.
- + * Original author "Antonio Nati" and the web URL
- + * "http://www.interazioni.it/opensource"
- + * must be indicated in every related work or web page
- + *
- + */
- +
- +/*
- + * the following line enables debugging of chkuser
- + */
- +/* #define CHKUSER_DEBUG */
- +
- +/*
- + * The following line moves DEBUG output from STDOUT (default) to STDERR
- + * Example of usage within sh: ./qmail-smtpd 2> /var/log/smtpd-debug.log
- + */
- +/* #define CHKUSER_DEBUG_STDERR */
- +
- +/*
- + * Uncomment the following define if you want chkuser ALWAYS enabled.
- + * If uncommented, it will check for rcpt existance despite any .qmail-default
- + * setting.
- + * So, unsomments this if you are aware that ALL rcpt in all domains will be
- + * ALWAYS checked.
- + */
- +/* #define CHKUSER_ALWAYS_ON */
- +
- +/*
- + * The following defines which virtual manager is used.
- + * Up to know, only vpopmail, but versions with pure qmail are in the mind.
- + */
- +#define CHKUSER_VPOPMAIL
- +
- +/*
- + * Uncomment the following line if you want chkuser to work depending on a VARIABLE setting
- + * VALUE HERE DEFINED is the name of the variable
- + * Values admitted inside the variable: NONE | ALWAYS | DOMAIN
- + * NONE = chkuser will not work
- + * ALWAYS = chkuser will work always
- + * DOMAIN = chkuser will work depending by single domain settings
- + * if CHKUSER_ALWAYS_ON is defined, this define is useless
- + * if CHKUSER_STARTING_VARIABLE is defined, and no variable or no value is set, then chkuser is disabled
- + */
- +/* #define CHKUSER_STARTING_VARIABLE "CHKUSER_START" */
- +
- +/*
- + * Uncomment this to enable uid/gid changing
- + * (switching UID/GID is NOT compatible with TLS; you may keep this commented if you have TLS)
- + */
- +/* EDIT #define CHKUSER_ENABLE_UIDGID */
- +
- +/*
- + * Uncomment this to check if a domain is ALWAYS specified in rcpt addresses
- + */
- +/* EDIT #define CHKUSER_DOMAIN_WANTED */
- +
- +/*
- + * Uncomment this to check for vpopmail users
- + */
- +#define CHKUSER_ENABLE_USERS
- +
- +/*
- + * Uncomment this to check for alias
- + */
- +#define CHKUSER_ENABLE_ALIAS
- +
- +/*
- + * The following #define set the character used for lists extensions
- + * be careful: this is a single char '-' definition, not a "string"
- + */
- +#define CHKUSER_EZMLM_DASH '-'
- +
- +/*
- + * Uncomment this to set an alternative way to check for bouncing enabling;
- + * with this option enabled, the file here defined
- + * will be searched, inside the domain dir, in order to check if bouncing is enabled
- + * The content of this file is not important, just it's existence is enough
- + */
- +/* #define CHKUSER_SPECIFIC_BOUNCING ".qmailchkuser-bouncing" */
- +
- +/*
- + * This is the string to look for inside .qmail-default
- + * Be careful, chkuser looks within the first 1023 characters of .qmail-default for
- + * this string (despite the line containing the string is working or commented).
- + */
- +#define CHKUSER_BOUNCE_STRING "bounce-no-mailbox"
- +
- +/*
- + * This is to enable auth open checking
- + * it is useful to avoid bouncing if MySQL/LDAP/PostGRES/etc are down or not reachable
- + */
- +/* #define CHKUSER_ENABLE_VAUTH_OPEN */
- +
- +/*
- + * Uncomment to enable logging of rejected recipients and variuos limits reached
- + */
- +#define CHKUSER_ENABLE_LOGGING
- +
- +/*
- + * Uncomment to enable logging of "good" rcpts
- + * valid only if CHKUSER_ENABLE_LOGGING is defined
- + */
- +#define CHKUSER_LOG_VALID_RCPT
- +
- +/*
- + * Uncomment to enable usage of a variable escluding any check on the sender.
- + * The variable should be set in tcp.smtp for clients, with static IP, whose mailer
- + * is composing bad sender addresses
- + */
- +/* #define CHKUSER_SENDER_NOCHECK_VARIABLE "SENDER_NOCHECK" */
- +
- +/*
- + * Uncomment to enable usage of "#" and "+" characters within sender address
- + * This is used by SRS (Sender Rewriting Scheme) products
- + */
- +#define CHKUSER_ALLOW_SENDER_SRS
- +
- +/*
- + * If you need more additional characters to be accepted within sender address
- + * uncomment one of the following #define and edit the character value.
- + * Be careful to use '*' (single hiphen) and NOT "*" (double hiphen) around the
- + * wanted char.
- + */
- +/* #define CHKUSER_ALLOW_SENDER_CHAR_1 '$' */
- +/* #define CHKUSER_ALLOW_SENDER_CHAR_2 '%' */
- +/* #define CHKUSER_ALLOW_SENDER_CHAR_3 '£' */
- +/* #define CHKUSER_ALLOW_SENDER_CHAR_4 '?' */
- +/* #define CHKUSER_ALLOW_SENDER_CHAR_5 '*' */
- +
- +/*
- + * The following #define sets the minimum length of a domain:
- + * as far as I know, "k.st" is the shortest domain, so 4 characters is the
- + * minimum length.
- + * This value is used to check formally a domain name validity.
- + * if CHKUSER_SENDER_FORMAT is undefined, no check on length is done.
- + * If you comment this define, no check on length is done.
- + */
- +#define CHKUSER_MIN_DOMAIN_LEN 4
- +
- +/*
- + * Uncomment to enable logging of "good" senders
- + * valid only if CHKUSER_ENABLE_LOGGING is defined
- + */
- +#define CHKUSER_LOG_VALID_SENDER
- +
- +/*
- + * Uncomment to define a variable which contains the max recipients number
- + * this will return always error if total recipients exceed this limit.
- + * The first reached, between CHKUSER_RCPT_LIMIT_VARIABLE and CHKUSER_WRONGRCPT_LIMIT_VARIABLE,
- + * makes chkuser rejecting everything else
- + */
- +#define CHKUSER_RCPT_LIMIT_VARIABLE "CHKUSER_RCPTLIMIT"
- +
- +/*
- + * Uncomment to define a variable which contains the max unknown recipients number
- + * this will return always error if not existing recipients exceed this limit.
- + * The first reached, between CHKUSER_RCPT_LIMIT_VARIABLE and CHKUSER_WRONGRCPT_LIMIT_VARIABLE,
- + * makes chkuser rejecting everything else
- + */
- +#define CHKUSER_WRONGRCPT_LIMIT_VARIABLE "CHKUSER_WRONGRCPTLIMIT"
- +
- +/*
- + * Uncomment to define the variable containing the percent to check for.
- + * Remember to define externally (i.e. in tcp.smtp) the environment variable containing
- + * the limit percent.
- + * If the variable is not defined, or it is <= 0, quota checking is not performed.
- + */
- +#define CHKUSER_MBXQUOTA_VARIABLE "CHKUSER_MBXQUOTA"
- +
- +/*
- + * Delay to wait for each not existing recipient
- + * value is expressed in milliseconds
- + */
- +#define CHKUSER_ERROR_DELAY 1000
- +
- +/*
- + * Uncomment to consider rcpt errors on address format and MX as intrusive
- + *
- + */
- +#define CHKUSER_RCPT_DELAY_ANYERROR
- +
- +/*
- + * Uncomment to consider sender errors on address format and MX as intrusive
- + *
- + */
- +#define CHKUSER_SENDER_DELAY_ANYERROR
- +
- +#define CHKUSER_NORCPT_STRING "511 sorry, no mailbox here by that name (#5.1.1 - chkuser)\r\n"
- +#define CHKUSER_RESOURCE_STRING "430 system temporary unavailable, try again later (#4.3.0 - chkuser)\r\n"
- +#define CHKUSER_MBXFULL_STRING "522 sorry, recipient mailbox is full (#5.2.2 - chkuser)\r\n"
- +#define CHKUSER_MAXRCPT_STRING "571 sorry, reached maximum number of recipients for one session (#5.7.1 - chkuser)\r\n"
- +#define CHKUSER_MAXWRONGRCPT_STRING "571 sorry, you are violating our security policies (#5.1.1 - chkuser)\r\n"
- +#define CHKUSER_DOMAINMISSING_STRING "511 sorry, you must specify a domain (#5.1.1 - chkuser)\r\n"
- +#define CHKUSER_RCPTFORMAT_STRING "511 sorry, recipient address has invalid format (#5.1.1 - chkuser)\r\n"
- +#define CHKUSER_RCPTMX_STRING "511 sorry, can't find a valid MX for rcpt domain (#5.1.1 - chkuser)\r\n"
- +#define CHKUSER_SENDERFORMAT_STRING "571 sorry, sender address has invalid format (#5.7.1 - chkuser)\r\n"
- +#define CHKUSER_SENDERMX_STRING "511 sorry, can't find a valid MX for sender domain (#5.1.1 - chkuser)\r\n"
- +#define CHKUSER_INTRUSIONTHRESHOLD_STRING "571 sorry, you are violating our security policies (#5.7.1 - chkuser)\r\n"
- +#define CHKUSER_NORELAY_STRING "553 sorry, that domain isn't in my list of allowed rcpthosts (#5.5.3 - chkuser)\r\n"
- +
- +/***************************************************
- + *
- + * new/modified defines in/from 2.0.6
- + *
- + **************************************************/
- +
- +/*
- + * Before version 5.3.25, vpopmail used the function vget_real_domain()
- + * to get the real name of a domain (useful if rcpt domain is aliasing
- + * another domain).
- + * From version 5.3.25, this call is not available and has been
- + * substituted by other calls.
- + *
- + * must be enabled if vpopmail version< 5.3.5
- + * must be disabled if vpopmail version => 5.3.5 *
- + */
- +/* #define CHKUSER_ENABLE_VGET_REAL_DOMAIN */
- +
- +/***************************************************
- + *
- + * new/modified defines in/from 2.0.7
- + *
- + **************************************************/
- +
- +/*
- + * Uncomment next define to accept recipients for
- + * aliases that have a -default extension
- + */
- +#define CHKUSER_ENABLE_ALIAS_DEFAULT
- +
- +
- +/*
- + * Uncomment to enable usage of "#" and "+" characters within rcpt address
- + * This is used by SRS (Sender Rewriting Scheme) products
- + */
- +#define CHKUSER_ALLOW_RCPT_SRS
- +
- +/*
- + * If you need more additional characters to be accepted within rcpt address
- + * uncomment one of the following #define and edit the character value.
- + * Be careful to use '*' (single hiphen) and NOT "*" (double hiphen) around the
- + * wanted char.
- + */
- +/* #define CHKUSER_ALLOW_RCPT_CHAR_1 '$' */
- +/* #define CHKUSER_ALLOW_RCPT_CHAR_2 '%' */
- +/* #define CHKUSER_ALLOW_RCPT_CHAR_3 '£' */
- +/* #define CHKUSER_ALLOW_RCPT_CHAR_4 '?' */
- +/* #define CHKUSER_ALLOW_RCPT_CHAR_5 '*' */
- +
- +/*
- + * This define has been eliminated.
- + * Turning it ON or OFF has no effect, as we consider the existence
- + * of #define VALIAS inside ~vpopmail/include/vpopmail_config.h
- + */
- +/* #define CHKUSER_ENABLE_VALIAS */
- +
- +/*
- + * Uncomment this to enable user extension on names (i.e. TMDA)
- + * (for mailing lists this is done without checking this define)
- + * This define substitutes #define CHKUSER_ENABLE_EXTENSIONS
- + */
- +/* #define CHKUSER_ENABLE_USERS_EXTENSIONS */
- +
- +/*
- + * Enables checking for EZMLM lists
- + * this define substitutes #define CHKUSER_ENABLE_LISTS
- + *
- + */
- +#define CHKUSER_ENABLE_EZMLM_LISTS
- +
- +/*
- + * Help identifying remote authorized IPs giving them a descriptive name
- + * Can be put in tcp.smtp, and will be displayed inside chkuser log
- + * Substitutes RELAYCLIENT in chkuser logging
- + */
- +#define CHKUSER_IDENTIFY_REMOTE_VARIABLE "CHKUSER_IDENTIFY"
- +
- +/*
- + * The following #define set the character used for users extensions
- + * be careful: this is a single char '-' definition, not a "string"
- + * this define substitutes #define CHKUSER_EXTENSION_DASH
- + * MUST be defined if CHKUSER_ENABLE_USERS_EXTENSIONS is defined
- + */
- +#define CHKUSER_USERS_DASH '-'
- +
- +/*
- + * New error strings for SOFT DNS problems
- + */
- +#define CHKUSER_RCPTMX_TMP_STRING "451 DNS temporary failure (#4.5.1 - chkuser)\r\n"
- +#define CHKUSER_SENDERMX_TMP_STRING "451 DNS temporary failure (#4.5.1 - chkuser)\r\n"
- +
- +/*
- + * Enables checking for mailman lists
- + *
- + */
- +/* #define CHKUSER_ENABLE_MAILMAN_LISTS */
- +
- +/*
- + * Identifies the pattern string to be searched within mailman aliases
- + *
- + */
- +#define CHKUSER_MAILMAN_STRING "mailman"
- +
- +/*
- + * The following #define set the character used for mailman lists extensions
- + * be careful: this is a single char '-' definition, not a "string"
- + */
- +#define CHKUSER_MAILMAN_DASH '-'
- +
- +
- +/*
- + * Enables final clean-up routine of chkuser
- + * This routine cleans open DB connections used for checking users and valiases
- + */
- +#define CHKUSER_DB_CLEANUP
- +
- +/***************************************************
- + *
- + * new/modified defines in/from 2.0.8
- + *
- + **************************************************/
- +
- +/*
- + * The following defines are NO MORE used. NULL SENDER rejecting breaks RFC
- + * compatibility, and makes harder to handle e-mail receipts.
- + * Please comment or delete them from your chkuser_settings.h.
- + */
- +/* #define CHKUSER_ACCEPT_NULL_SENDER */
- +/* #define CHKUSER_ENABLE_NULL_SENDER_WITH_TCPREMOTEHOST */
- +
- +/*
- + * Uncomment to enable checking of user and domain format for rcpt addresses
- + * user = [a-z0-9_-]
- + * domain = [a-z0-9-.] with not consecutive "-.", not leading or ending "-."
- + */
- +/* #define CHKUSER_RCPT_FORMAT */
- +
- +/*
- + * Uncomment to enable checking of domain MX for rcpt addresses
- + * It works on any rcpt address domain that is not inside rcpthosts
- + */
- +/* #define CHKUSER_RCPT_MX */
- +
- +/*
- + * Uncomment to enable checking of user and domain format for sender address
- + * user = [a-z0-9_-]
- + * domain = [a-z0-9-.] with not consecutive "-.", not leading or ending "-."
- + */
- +/* #define CHKUSER_SENDER_FORMAT */
- +
- +/*
- + * Uncomment to enable checking of domain MX for sender address
- + * it works on the first rcpt address, despite of any domain setting on chkuser
- + */
- +/* #define CHKUSER_SENDER_MX */
- +
- +/*
- + * Delay to add, for each not existing recipient, to the initial CHKUSER_ERROR_DELAY value
- + * value is expressed in milliseconds
- + */
- +#define CHKUSER_ERROR_DELAY_INCREASE 300
- +
- diff -Naur qmail-1.03.orig/conf-cc qmail-1.03/conf-cc
- --- qmail-1.03.orig/conf-cc Sun Dec 24 15:24:55 2006
- +++ qmail-1.03/conf-cc Mon Dec 25 23:42:57 2006
- @@ -1 +1 @@
- -cc -O -pipe -funroll-loops -march=pentiumpro -I/usr/include -L/usr/lib -DTLS
- +cc -O -pipe -funroll-loops -march=pentiumpro -I/usr/include -L/usr/lib -DTLS -I/usr/local/vpopmail/include
- diff -Naur qmail-1.03.orig/qmail-smtpd.c qmail-1.03/qmail-smtpd.c
- --- qmail-1.03.orig/qmail-smtpd.c Mon Dec 25 23:39:28 2006
- +++ qmail-1.03/qmail-smtpd.c Mon Dec 25 23:41:17 2006
- @@ -45,6 +45,10 @@
- int ssl_rfd = -1, ssl_wfd = -1; /* SSL_get_Xfd() are broken */
- #endif
-
- +/* start chkuser code */
- +#include "chkuser.h"
- +/* end chkuser code */
- +
- int safewrite(fd,buf,len) int fd; char *buf; int len;
- {
- int r;
- @@ -330,6 +334,9 @@
- flagsize = 0;
- mailfrom_parms(arg);
- if (flagsize) { err_size(); return; }
- +/* start chkuser code */
- + if (chkuser_sender (&addr) != CHKUSER_OK) { return; }
- +/* end chkuser code */
- if (!(spp_val = spp_mail())) return;
- flagbarfspf = 0;
- if (spp_val == 1) {
- @@ -397,9 +404,8 @@
- if (!addrparse(arg)) { err_syntax(); return; }
- if (flagbarf) { err_bmf(); return; }
- if (flagbarfspf) { err_spf(); return; }
- - if (!relayclient) allowed = addrallowed();
- - else allowed = 1;
- - if (!(spp_val = spp_rcpt(allowed))) return;
- +/*
- + * Original code substituted by chkuser code
- if (relayclient) {
- --addr.len;
- if (!stralloc_cats(&addr,relayclient)) die_nomem();
- @@ -404,6 +413,23 @@
- else if (spp_val == 1) {
- if (!allowed) { err_nogateway(); return; }
- }
- + * end of substituted code
- + */
- +
- +/* start chkuser code */
- + switch (chkuser_realrcpt (&mailfrom, &addr)) {
- + case CHKUSER_KO:
- + return;
- + break;
- +
- + case CHKUSER_RELAYING:
- + --addr.len;
- + if (!stralloc_cats(&addr,relayclient)) die_nomem();
- + if (!stralloc_0(&addr)) die_nomem();
- + break;
- + }
- +/* end chkuser code */
- + if (!(spp_val = spp_rcpt(1))) return;
- spp_rcpt_accepted();
- if (!stralloc_cats(&rcptto,"T")) die_nomem();
- if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
-