Hi All,

I've been working on including an additional feature that has been
requested by many people.

The feature that I'm referring to goes like this:

"A particular user should only be able to send emails to local domains."

To address this problem, I've introduced a new 'accountStatus' flag,
called 'localonly'. This flag is checked just after a 'mail from:' is
sent to qmail-smtpd. 

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. 

Please provide your valuable comments, suggestions and feedback on the
implementation. 

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	Tue Mar 21 15:36:08 2006
+++ qmail-1.03/Makefile	Tue Mar 21 15:32:40 2006
@@ -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	Tue Mar 21 15:36:09 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	Tue Mar 21 15:36:09 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	Tue Mar 21 15:36:09 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	Tue Mar 21 15:36:09 2006
+++ qmail-1.03/qmail-smtpd.c	Tue Mar 21 15:34:28 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,61 @@
 
 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;
+    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,9 +957,12 @@
   }
 
   /* check if we are authenticated, if yes enable relaying */
-  if (flagauthok && relayclient == 0) {
-    relayclient = "";
-    if (!env_put("RELAYCLIENT=")) die_nomem();
+  if (localonlycheck(addr.s)) {
+    logline2(3,"allow relay to: ", addr.s);
+    if (flagauthok && relayclient == 0) {
+      relayclient = "";
+      if (!env_put("RELAYCLIENT=")) die_nomem();
+    }
   }
 
   /* smtp size check */
@@ -1732,6 +1790,8 @@
 
 int main(int argc, char **argv)
 {
+  if (read_controls(ctrls) == -1)
+		die_control();
 #ifdef TLS_SMTPD
   sig_alarmcatch(sigalrm);
 #endif
@@ -1761,4 +1821,3 @@
   /* NOTREACHED */
   return 1;
 }
-

Reply via email to