Hello All,
On Tue, 2006-03-21 at 16:09 +0530, B S Srinidhi wrote:
> If the *sender* is local, and if the 'accountStatus' has been set to
> "localonly", then we remove the RELAYCLIENT variable from the env, if
> set, and also disable relaying (even if the user has been
> authenticated). After this, when the sender provides an email address
> for 'rcpt to:' command and if the domain is not local, relaying is
> denied.
>
> If the *sender* is local, and if the 'accountStatus' flag is not set to
> 'localonly', then normal tests are performed to allow or deny relaying.
>
> Please find the patch against the qmail-ldap-1.03-20060201 patch.
There was a problem with my previous patch. If the user, whose
accountStatus is 'localonly', authenticates before sending the email,
(s)he will be allowed to send emails to non-local domains.
Many thanks to Alexandre Mioranza for trying out this patch and giving
his valuable feedback and also for reporting this bug.
I'm sending a new patch that fixes this problem. I once again solicit
comments and feedback on this patch.
Regards,
Srinidhi.
--
ASCII ribbon campaign ( ) B S Srinidhi
- against HTML email X http://srinidhi.deeproot.co.in
& vCards / \ DeepRoot Linux
diff -urN /tmp/qmail-1.03/Makefile qmail-1.03/Makefile
--- /tmp/qmail-1.03/Makefile Sat Apr 1 14:56:12 2006
+++ qmail-1.03/Makefile Tue Mar 21 15:32:40 2006
@@ -19,12 +19,12 @@
# -DQMQP_COMPRESS to use the QMQP on the fly compression (for clusters)
# -DQUOTATRASH to include the Trash in the quota calculation (normaly it is not)
# -DSMTPEXECCHECK to enable smtp DOS/Windows executable detection
-#LDAPFLAGS=-DQLDAP_CLUSTER -DEXTERNAL_TODO -DDASH_EXT -DDATA_COMPRESS -DQMQP_COMPRESS -DSMTPEXECCHECK
+LDAPFLAGS=-DQLDAP_CLUSTER -DEXTERNAL_TODO -DDASH_EXT -DDATA_COMPRESS -DQMQP_COMPRESS -DSMTPEXECCHECK -DBIGBROTHER -DALTQUEUE
# Perhaps you have different ldap libraries, change them here
-LDAPLIBS=-L/usr/local/lib -lldap -llber
+LDAPLIBS=-L/var/easypush/ldap/lib -lldap -llber
# and change the location of the include files here
-LDAPINCLUDES=-I/usr/local/include
+LDAPINCLUDES=-I/var/easypush/ldap/include
# on Slowaris you need -lresolv and probably a LD_RUN_PATH added like this:
#LDAPLIBS=-L/opt/OpenLDAP/lib -lldap -llber -lresolv -R/opt/OpenLDAP/lib
# for example on my Linux box I use:
@@ -33,7 +33,7 @@
#LDAPINCLUDES=-I/opt/OpenLDAP/include
# ZLIB needed for -DDATA_COMPRESS and -DQMQP_COMPRESS
-#ZLIB=-lz
+ZLIB=-lz
# or you installed zlib in a different path you can use something like this
#ZLIB=-L/opt/zlib/lib -lz
#ZINCLUDES=-I/opt/zlib/include
@@ -43,13 +43,13 @@
# use -DTLS_REMOTE to enable tls support in qmail-remote
# use -DTLS_SMTPD to enable tls support in qmail-smtpd
# use -DTLSDEBUG to enable additional tls debug information in qmail-remote
-#TLS=-DTLS_REMOTE -DTLS_SMTPD
+TLS=-DTLS_REMOTE -DTLS_SMTPD
# Path to OpenSSL includes
-#TLSINCLUDES=-I/usr/local/include
+TLSINCLUDES=-I/usr/include/openssl/
# Path to OpenSSL libraries
-#TLSLIBS=-L/usr/local/lib -lssl -lcrypto
+TLSLIBS=-L/usr/lib -lssl -lcrypto
# Path to OpenSSL binary
-#OPENSSLBIN=/usr/local/bin/openssl
+OPENSSLBIN=/usr/bin/openssl
#OPENSSLBIN=openssl
# to make the Netscape download progress bar work with qmail-pop3d
@@ -57,13 +57,13 @@
MNW=-DMAKE_NETSCAPE_WORK
# to enable the auto-maildir-make feature uncomment the next line
-#MDIRMAKE=-DAUTOMAILDIRMAKE
+MDIRMAKE=-DAUTOMAILDIRMAKE
# to enable the auto-homedir-make feature uncomment the next line
-#HDIRMAKE=-DAUTOHOMEDIRMAKE
+HDIRMAKE=-DAUTOHOMEDIRMAKE
# on most systems we need this to make auth_pop and auth_imap
-#SHADOWLIBS=-lcrypt
+SHADOWLIBS=-lcrypt
# OpenBSD and other Systems do not have libcrypt, so comment the line out
# if you get linking problems.
# To use shadow passwords under some Linux OS, uncomment the next two lines.
@@ -73,7 +73,7 @@
# to enable the possibility to log and debug imap and pop uncoment the
# next line
-#DEBUG=-DDEBUG
+DEBUG=-DDEBUG
# WARNING: you need a NONE DEBUG auth_* to run with inetd
# for profiling ...
@@ -2068,8 +2068,9 @@
received.o date822fmt.o now.o qmail.o execcheck.o cdb.a \
smtpcall.o coe.o fd.a seek.a wait.a datetime.a getln.a \
open.a sig.a case.a env.a stralloc.a alloc.a substdio.a \
- error.a fs.a auto_qmail.o dns.o str.a auto_break.o \
- `cat dns.lib` `cat socket.lib` $(TLSLIBS) $(ZLIB)
+ error.a fs.a auto_qmail.o dns.o str.a auto_break.o qldap.a \
+ byte_repl.o byte_zero.o str_rchr.o read-ctrl.o \
+ `cat dns.lib` `cat socket.lib` $(LDAPLIBS) $(TLSLIBS) $(ZLIB)
qmail-smtpd.0: \
qmail-smtpd.8
@@ -2081,8 +2082,8 @@
error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \
substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h rbl.h \
-qmail-ldap.h auto_break.h
- ./compile $(LDAPFLAGS) $(TLS) $(TLSINCLUDES) $(ZINCLUDES) \
+qmail-ldap.h auto_break.h qlx.h qldap.h qldap-errno.h
+ ./compile $(LDAPFLAGS) $(TLS) $(TLSINCLUDES) $(ZINCLUDES) $(LDAPINCLUDES) \
qmail-smtpd.c
qmail-smtpd.run: \
diff -urN /tmp/qmail-1.03/qldap.c qmail-1.03/qldap.c
--- /tmp/qmail-1.03/qldap.c Sat Apr 1 14:56:13 2006
+++ qmail-1.03/qldap.c Fri Mar 10 18:00:09 2006
@@ -92,7 +92,7 @@
#define CHECK(x, y) \
do { \
if (check_next_state((x), (y)) == 0) { \
- logit(128, "qldap: bad state transition %i -> %i",\
+ logit(128, "qldap: bad state transition %i -> %i\n",\
(x)->state, y); \
(x)->state = ERROR; \
return FAILED; \
@@ -683,7 +683,10 @@
*status = STATUS_DELETE;
else if (!case_diffs(ldap_attr.s, ISACTIVE_NOACCESS))
*status = STATUS_NOACCESS;
+ else if (!case_diffs(ldap_attr.s, ISACTIVE_LOCALONLY))
+ *status = STATUS_LOCALONLY;
else *status = STATUS_OK; /* default to OK */
+
/* perhaps we should spill out a warning for unknown settings */
return OK;
}
@@ -1054,4 +1057,3 @@
return 0;
}
}
-
diff -urN /tmp/qmail-1.03/qmail-ldap.h qmail-1.03/qmail-ldap.h
--- /tmp/qmail-1.03/qmail-ldap.h Sat Apr 1 14:56:13 2006
+++ qmail-1.03/qmail-ldap.h Thu Mar 9 17:32:06 2006
@@ -136,6 +136,7 @@
#define ISACTIVE_DELETE "deleted"
#define ISACTIVE_NOACCESS "noaccess"
#define ISACTIVE_ACTIVE "active"
+#define ISACTIVE_LOCALONLY "localonly"
/*********************************************************************
ldap variables used in qmail-group
@@ -160,6 +161,7 @@
normaly you can stop editing here
*********************************************************************/
/* the same values as ints */
+#define STATUS_LOCALONLY 4
#define STATUS_DELETE 3
#define STATUS_BOUNCE 2
#define STATUS_NOACCESS 1
diff -urN /tmp/qmail-1.03/qmail-ldaplookup.c qmail-1.03/qmail-ldaplookup.c
--- /tmp/qmail-1.03/qmail-ldaplookup.c Sat Apr 1 14:56:13 2006
+++ qmail-1.03/qmail-ldaplookup.c Thu Mar 9 17:32:40 2006
@@ -332,6 +332,10 @@
output(subfdout, "%s: %s\n",
LDAP_ISACTIVE, ISACTIVE_ACTIVE);
break;
+ case STATUS_LOCALONLY:
+ output(subfdout, "%s: %s\n",
+ LDAP_ISACTIVE, ISACTIVE_LOCALONLY);
+ break;
case STATUS_UNDEF:
output(subfdout, "%s: %s\n", LDAP_ISACTIVE,
"undefined -> active");
diff -urN /tmp/qmail-1.03/qmail-smtpd.c qmail-1.03/qmail-smtpd.c
--- /tmp/qmail-1.03/qmail-smtpd.c Sat Apr 1 14:56:13 2006
+++ qmail-1.03/qmail-smtpd.c Tue Mar 28 17:59:31 2006
@@ -6,6 +6,7 @@
#include "subfd.h"
#include "alloc.h"
#include "auto_qmail.h"
+#include "qlx.h"
#include "auto_break.h"
#include "control.h"
#include "received.h"
@@ -23,12 +24,16 @@
#include "now.h"
#include "exit.h"
#include "rcpthosts.h"
+#include "read-ctrl.h"
#include "rbl.h"
#include "timeoutread.h"
#include "timeoutwrite.h"
#include "commands.h"
#include "dns.h"
#include "smtpcall.h"
+#include "output.h"
+#include "qldap.h"
+#include "qldap-errno.h"
#include "qmail-ldap.h"
#include "limit.h"
#ifdef SMTPEXECCHECK
@@ -877,11 +882,62 @@
struct qmail qqt;
+ctrlfunc ctrls[] = {
+ qldap_ctrl_trylogin,
+ qldap_ctrl_generic,
+ 0 };
+
+/* Check the status of the account. If its 'localonly', then unset relayclient */
+int localonlycheck(char *localaddr)
+{
+ const char *attrs[] = { LDAP_ISACTIVE, 0};
+ char *filter;
+ struct qldap *q;
+ int done;
+ int rv;
+ int status;
+
+ /* taken from qmail-lspawn.c :( */
+ q = qldap_new();
+ if (q == 0)
+ _exit(QLX_NOMEM);
+
+ rv = qldap_open(q);
+ if (rv != OK) goto fail;
+ rv = qldap_bind(q, 0, 0);
+ if (rv != OK) goto fail;
+
+ done = 0;
+ filter = filter_mail(localaddr, &done);
+ if (filter == 0) { rv = ERRNO; goto fail; }
+
+ rv = qldap_lookup(q, filter, attrs);
+ if (rv != OK) goto fail;
+
+ /* check if the ldap entry is localonly */
+ rv = qldap_get_status(q, &status);
+ if (rv != OK) goto fail;
+ if (status == STATUS_LOCALONLY) {
+ logline(3,"account status is 'localonly'");
+ relayclient = 0;
+ flagauthok = 0;
+ if (!env_unset("RELAYCLIENT=")) die_nomem();
+ qldap_free(q);
+ return 1;
+ }
+
+fail:
+ qldap_free(q);
+ logline(3,"account status is not 'localonly'");
+ return 0;
+}
+
void smtp_mail(char *arg)
{
unsigned int i,j;
char *rblname;
int bounceflag = 0;
+ int islocal;
/* address syntax check */
if (!addrparse(arg))
@@ -902,11 +958,21 @@
}
/* check if we are authenticated, if yes enable relaying */
- if (flagauthok && relayclient == 0) {
- relayclient = "";
- if (!env_put("RELAYCLIENT=")) die_nomem();
+ if (localonlycheck(addr.s) == 0) {
+ logline2(3,"allow relay to: ", addr.s);
+ if (flagauthok && relayclient == 0) {
+ relayclient = "";
+ if (!env_put("RELAYCLIENT=")) die_nomem();
+ }
+ } else {
+ if (!addrallowed()) {
+ err_nogateway();
+ logline2(3,"no mail relay for 'rcpt to': ",addr.s);
+ if (errdisconnect) err_quit();
+ return;
+ }
}
-
+
/* smtp size check */
if (databytes && !sizelimit(arg))
{
@@ -1732,6 +1798,8 @@
int main(int argc, char **argv)
{
+ if (read_controls(ctrls) == -1)
+ die_control();
#ifdef TLS_SMTPD
sig_alarmcatch(sigalrm);
#endif
@@ -1761,4 +1829,3 @@
/* NOTREACHED */
return 1;
}
-