Index: qmail-1.03/Makefile =================================================================== --- qmail-1.03.orig/Makefile +++ qmail-1.03/Makefile @@ -19,12 +19,34 @@ # -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 +# -DCOURIER use Courier POP3d/IMAPd instead of Qmail POP3d +#LDAPFLAGS=-DQLDAP_CLUSTER -DEXTERNAL_TODO -DDASH_EXT -DDATA_COMPRESS -DQMQP_COMPRESS -DSMTPEXECCHECK -DCOURIER + +# * These are some options to securly connect to the LDAP server +# -DSECUREBIND_SASL Bind using SASL +# -DSECUREBIND_SSL Encrypt the channel with SSL +# -DSECUREBIND_TLS Encrypt the channel with TLS (SSL v3) +# -DSECUREBIND_ALL All of the above... +#SECUREBIND=-DSECUREBIND_ALL + +# * Log authentication success/failures in auth_{pop,imap,smtp} +#SYSLOGAUTH=-DSYSLOGAUTH + +# -DUSE_RFC2307 -> Follow the RFC2307 +# -DUSE_RFC822 -> Follow the RFC822 +# See the QLDAPINSTALL file for more about this. +#RFCFLAGS=-DUSE_RFC2307 -DUSE_RFC822 + +# to enable having the configuration (~control/* in the LDAP database +# to, uncomment the following line and read QLDAPINSTALL. +# -DUSE_CONTROLDB Search LDAP for control files +# -DQLDAP_BAILOUT First search LDAP, then FS +#CONTROLDB=-DUSE_CONTROLDB -DQLDAP_BAILOUT # Perhaps you have different ldap libraries, change them here -LDAPLIBS=-L/usr/local/lib -lldap -llber +#LDAPLIBS=-L/usr/local/lib -lldap -llber # and change the location of the include files here -LDAPINCLUDES=-I/usr/local/include +#LDAPINCLUDES=-I/usr/local/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: @@ -54,7 +76,7 @@ LDAPINCLUDES=-I/usr/local/include # to make the Netscape download progress bar work with qmail-pop3d # uncomment the next line (allready done) -MNW=-DMAKE_NETSCAPE_WORK +#MNW=-DMAKE_NETSCAPE_WORK # to enable the auto-maildir-make feature uncomment the next line #MDIRMAKE=-DAUTOMAILDIRMAKE @@ -84,10 +106,65 @@ MNW=-DMAKE_NETSCAPE_WORK BACKUPPATH=/backup/qmail-backup/qmail-ldap.`date "+%Y%m%d-%H%M"`.tar # STOP editing HERE !!! +ifdef DEBIAN +DEBUG=-DDEBUG + +LDAPFLAGS=-DALTQUEUE -DBIGBROTHER -DQLDAP_CLUSTER -DEXTERNAL_TODO -DBIGTODO -DDASH_EXT -DDATA_COMPRESS -DQMQP_COMPRESS -DIGNOREVERISIGN -DQUOTATRASH -DCOURIER + +SECUREBIND=-DSECUREBIND_SSL -DSECUREBIND_TLS +RFCFLAGS=-DUSE_RFC2307 +CONTROLDB=-DUSE_CONTROLDB -DQLDAP_BAILOUT +SYSLOGAUTH=-DSYSLOGAUTH + +LDAPLIBS=-L/usr/lib -lldap -llber +LDAPINCLUDES=-I/usr/include + +ZLIB=-L/usr/lib -lz +ZINCLUDES=-I/usr/include + +TLS=-DTLS_REMOTE -DTLS_SMTPD +TLSINCLUDES=-I/usr/include +TLSLIBS=-L/usr/lib -lssl -lcrypto +OPENSSLBIN=/usr/bin/openssl + +MDIRMAKE=-DAUTOMAILDIRMAKE +HDIRMAKE=-DAUTOHOMEDIRMAKE +SHADOWLIBS=-lcrypt +endif + # Don't edit Makefile! Use conf-* for configuration. SHELL=/bin/sh +ifdef LDAPFLAGS +QLDAPLIB=qldap.a +else +ifdef SECUREBIND +QLDAPLIB=qldap.a +else +ifdef CONTROLDB +QLDAPLIB=qldap.a +endif +endif +endif + +ifdef SECUREBIND +SECUREBINDLIBS=getopt.a substdio.a +SECUREBINDLIB1=case_diffb.o constmap.o +endif + +ifdef CONTROLDB +NEWLDAPPROGLIBS=control.o stralloc.a fs.a +ifdef DEBUG +CONTROLLIBS=read-ctrl.o case.a env.a +else +CONTROLLIBS=read-ctrl.o case.a +endif +endif + +# This sums it up nice and correctly, I think! +LDAPFLAGS := $(LDAPFLAGS) $(DEBUG) $(CONTROLDB) $(RFCFLAGS) $(SECUREBIND) + default: it ldap ldap: qmail-quotawarn qmail-reply auth_pop auth_imap auth_smtp digest \ @@ -116,14 +193,14 @@ compile alloc_re.c alloc.h byte.h auth_imap: \ load auth_imap.o auth_mod.o checkpassword.o passwd.o digest_md4.o \ digest_md5.o digest_rmd160.o digest_sha1.o base64.o read-ctrl.o getopt.a \ -control.o dirmaker.o mailmaker.o qldap.a localdelivery.o locallookup.o \ +control.o dirmaker.o mailmaker.o $(QLDAPLIB) localdelivery.o locallookup.o \ pbsexec.o constmap.o getln.a strerr.a substdio.a stralloc.a env.a wait.a \ dns.o ip.o ipalloc.o ipme.o alloc.a str.a case.a fs.a error.a timeoutconn.o \ timeoutread.o ndelay.a open.a sig.a prot.o auto_uids.o auto_qmail.o \ dns.lib socket.lib ./load auth_imap auth_mod.o checkpassword.o passwd.o digest_md4.o \ digest_md5.o digest_rmd160.o digest_sha1.o base64.o read-ctrl.o \ - getopt.a control.o dirmaker.o mailmaker.o qldap.a localdelivery.o \ + getopt.a control.o dirmaker.o mailmaker.o $(QLDAPLIB) localdelivery.o \ locallookup.o pbsexec.o constmap.o getln.a strerr.a substdio.a \ stralloc.a env.a wait.a dns.o ip.o ipalloc.o ipme.o alloc.a str.a \ case.a fs.a error.a timeoutconn.o timeoutread.o ndelay.a open.a \ @@ -134,25 +211,25 @@ auth_imap.o: \ compile auth_imap.c alloc.h byte.h env.h error.h exit.h fmt.h pbsexec.h \ qldap-debug.h qldap-errno.h qmail-ldap.h readwrite.h scan.h sgetopt.h \ sig.h str.h stralloc.h substdio.h timeoutread.h auth_mod.h - ./compile $(LDAPFLAGS) $(DEBUG) auth_imap.c + ./compile $(LDAPFLAGS) $(SYSLOGAUTH) auth_imap.c auth_mod.o: \ compile auth_mod.c auth_mod.h checkpassword.h byte.h localdelivery.h \ locallookup.h output.h qldap.h qldap-debug.h qldap-errno.h stralloc.h \ read-ctrl.h dirmaker.h qldap-cluster.h select.h alloc.h - ./compile $(LDAPFLAGS) $(DEBUG) $(HDIRMAKE) $(MDIRMAKE) auth_mod.c + ./compile $(LDAPFLAGS) $(SYSLOGAUTH) $(HDIRMAKE) $(MDIRMAKE) auth_mod.c auth_pop: \ load auth_pop.o auth_mod.o checkpassword.o passwd.o digest_md4.o \ digest_md5.o digest_rmd160.o digest_sha1.o base64.o read-ctrl.o getopt.a \ -control.o dirmaker.o mailmaker.o qldap.a localdelivery.o locallookup.o \ +control.o dirmaker.o mailmaker.o $(QLDAPLIB) localdelivery.o locallookup.o \ pbsexec.o constmap.o getln.a strerr.a substdio.a stralloc.a env.a wait.a \ dns.o ip.o ipalloc.o ipme.o alloc.a str.a case.a fs.a error.a timeoutconn.o \ timeoutread.o ndelay.a open.a prot.o auto_uids.o auto_qmail.o \ dns.lib socket.lib ./load auth_pop auth_mod.o checkpassword.o passwd.o digest_md4.o \ digest_md5.o digest_rmd160.o digest_sha1.o base64.o read-ctrl.o \ - getopt.a control.o qldap.a dirmaker.o mailmaker.o localdelivery.o \ + getopt.a control.o $(QLDAPLIB) dirmaker.o mailmaker.o localdelivery.o \ locallookup.o pbsexec.o constmap.o getln.a strerr.a substdio.a \ stralloc.a env.a wait.a dns.o ip.o ipalloc.o ipme.o alloc.a str.a \ case.a fs.a error.a timeoutconn.o timeoutread.o ndelay.a open.a \ @@ -163,24 +240,24 @@ auth_pop.o: \ compile auth_pop.c byte.h env.h error.h exit.h pbsexec.h qldap-debug.h \ qldap-errno.h qmail-ldap.h readwrite.h sgetopt.h str.h stralloc.h substdio.h \ timeoutread.h auth_mod.h - ./compile $(LDAPFLAGS) $(DEBUG) auth_pop.c + ./compile $(LDAPFLAGS) $(SYSLOGAUTH) auth_pop.c auth_smtp: \ load auth_smtp.o checkpassword.o passwd.o digest_md4.o digest_md5.o \ -digest_rmd160.o digest_sha1.o base64.o read-ctrl.o control.o qldap.a \ +digest_rmd160.o digest_sha1.o base64.o read-ctrl.o control.o $(QLDAPLIB) \ constmap.o getln.a strerr.a substdio.a stralloc.a env.a alloc.a str.a \ case.a fs.a error.a open.a prot.o auto_uids.o auto_qmail.o ./load auth_smtp checkpassword.o passwd.o digest_md4.o \ digest_md5.o digest_rmd160.o digest_sha1.o base64.o read-ctrl.o \ - control.o qldap.a constmap.o getln.a strerr.a substdio.a stralloc.a \ + control.o $(QLDAPLIB) constmap.o getln.a strerr.a substdio.a stralloc.a \ env.a alloc.a str.a case.a fs.a error.a open.a prot.o auto_uids.o \ auto_qmail.o $(LDAPLIBS) $(SHADOWLIBS) - + auth_smtp.o: \ compile auth_smtp.c byte.h env.h error.h exit.h output.h qldap.h \ qldap-debug.h qldap-errno.h qmail-ldap.h read-ctrl.h str.h stralloc.h \ substdio.h checkpassword.h auth_mod.h - ./compile $(LDAPFLAGS) $(DEBUG) auth_smtp.c + ./compile $(LDAPFLAGS) $(SYSLOGAUTH) auth_smtp.c auto-ccld.sh: \ conf-cc conf-ld warn-auto.sh @@ -457,7 +534,7 @@ error.h fmt.h localdelivery.h passwd.h p qldap.h qldap-debug.h qldap-errno.h qmail-ldap.h scan.h str.h stralloc.h \ dns.h ipalloc.h ipme.h ndelay.h qldap-cluster.h readwrite.h select.h \ timeoutconn.h dirmaker.h mailmaker.h - ./compile $(LDAPFLAGS) $(LDAPINCLUDES) $(DEBUG) checkpassword.c + ./compile $(LDAPFLAGS) $(LDAPINCLUDES) checkpassword.c chkshsgr: \ load chkshsgr.o @@ -478,7 +555,7 @@ exit.h auto_spawn.h clean: \ TARGETS - rm -f `cat TARGETS` + rm -f `cat TARGETS` *~ .#* *.s coe.o: \ compile coe.c coe.h @@ -549,7 +626,7 @@ compile constmap.c constmap.h alloc.h ca control.o: \ compile control.c readwrite.h open.h getln.h stralloc.h gen_alloc.h \ substdio.h error.h control.h alloc.h scan.h - ./compile control.c + ./compile $(LDAPFLAGS) control.c date822fmt.o: \ compile date822fmt.c datetime.h fmt.h date822fmt.h @@ -615,7 +692,7 @@ compile trydrent.c direntry.h1 direntry. dirmaker.o: \ compile dirmaker.c dirmaker.h control.h qldap-debug.h qldap-errno.h \ stralloc.h wait.h - ./compile $(HDIRMAKE) $(DEBUG) dirmaker.c + ./compile $(HDIRMAKE) $(LDAPFLAGS) dirmaker.c dns.lib: \ tryrsolv.c compile load socket.lib dns.o ipalloc.o ip.o stralloc.a \ @@ -940,7 +1017,7 @@ compile hfield.c hfield.h hier.o: \ compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h - ./compile $(LDAPFLAGS) $(DEBUG) hier.c + ./compile $(LDAPFLAGS) hier.c home: \ home.sh conf-qmail @@ -993,7 +1070,7 @@ auto_uids.o auto_userl.o strerr.a substd install-big.o: \ compile install-big.c auto_qmail.h auto_split.h auto_uids.h fmt.h \ fifo.h - ./compile $(LDAPFLAGS) $(DEBUG) install-big.c + ./compile $(LDAPFLAGS) install-big.c install.o: \ compile install.c substdio.h strerr.h error.h open.h readwrite.h \ @@ -1055,12 +1132,12 @@ make-load warn-auto.sh systype localdelivery.o: \ compile localdelivery.c localdelivery.h control.h qldap-debug.h - ./compile $(DEBUG) localdelivery.c + ./compile $(LDAPFLAGS) localdelivery.c locallookup.o: \ compile locallookup.c locallookup.h checkpassword.h error.h getln.h \ localdelivery.h open.h passwd.h substdio.h - ./compile $(DEBUG) $(SHADOWOPTS) locallookup.c + ./compile $(LDAPFLAGS) $(SHADOWOPTS) locallookup.c lock.a: \ makelib lock_ex.o lock_exnb.o lock_un.o @@ -1270,49 +1347,55 @@ passwd.o: \ compile passwd.c base64.h byte.h case.h digest_md4.h digest_md5.h \ digest_rmd160.h digest_sha1.h qldap-debug.h qldap-errno.h str.h \ stralloc.h uint32.h passwd.h - ./compile $(LDAPFLAGS) $(DEBUG) passwd.c + ./compile $(LDAPFLAGS) passwd.c pbsadd: \ load pbsadd.o control.o now.o ip.o getln.a open.a env.a stralloc.a \ -alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o socket.lib +alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o socket.lib \ +$(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load pbsadd control.o now.o ip.o getln.a open.a env.a \ - stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a \ - auto_qmail.o `cat socket.lib` + stralloc.a alloc.a strerr.a substdio.a error.a $(QLDAPLIB) \ + $(CONTROLLIBS) str.a fs.a auto_qmail.o $(SECUREBINDLIBS) \ + `cat socket.lib` $(LDAPLIBS) pbsadd.o: \ compile pbsadd.c alloc.h auto_qmail.h byte.h control.h env.h error.h \ exit.h fmt.h ip.h now.h readwrite.h stralloc.h substdio.h - ./compile pbsadd.c + ./compile $(LDAPFLAGS) pbsadd.c pbscheck: \ load pbscheck.o control.o now.o timeoutread.o timeoutwrite.o \ ip.o getln.a open.a env.a stralloc.a alloc.a strerr.a substdio.a \ -error.a str.a fs.a auto_qmail.o socket.lib +error.a str.a fs.a auto_qmail.o socket.lib $(SECUREBINDLIBS) $(QLDAPLIB) \ +$(CONTROLLIBS) ./load pbscheck control.o now.o timeoutread.o timeoutwrite.o \ ip.o getln.a open.a env.a stralloc.a alloc.a strerr.a substdio.a \ - error.a str.a fs.a auto_qmail.o `cat socket.lib` + error.a $(QLDAPLIB) $(CONTROLLIBS) str.a fs.a auto_qmail.o \ + $(SECUREBINDLIBS) `cat socket.lib` $(LDAPLIBS) pbscheck.o: \ compile pbscheck.c alloc.h auto_qmail.h byte.h control.h env.h error.h \ exit.h fmt.h ip.h now.h readwrite.h str.h stralloc.h substdio.h timeoutread.h \ timeoutwrite.h - ./compile pbscheck.c + ./compile $(LDAPFLAGS) pbscheck.c pbsdbd: \ load pbsdbd.o control.o now.o ip.o ndelay.a getln.a open.a stralloc.a \ -alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o socket.lib +alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o socket.lib \ +$(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load pbsdbd control.o now.o ip.o ndelay.a getln.a open.a \ - stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a \ - auto_qmail.o `cat socket.lib` + stralloc.a alloc.a strerr.a substdio.a error.a $(QLDAPLIB) \ + $(CONTROLLIBS) str.a fs.a auto_qmail.o $(SECUREBINDLIBS) \ + `cat socket.lib` $(LDAPLIBS) pbsdbd.o: \ compile pbsdbd.c alloc.h auto_qmail.h byte.h control.h ip.h ndelay.h \ now.h stralloc.h strerr.h substdio.h uint32.h - ./compile pbsdbd.c + ./compile $(LDAPFLAGS) pbsdbd.c pbsexec.o: \ compile pbsexec.c pbsexec.h open.h qldap-debug.h wait.h - ./compile $(DEBUG) pbsexec.c + ./compile $(LDAPFLAGS) pbsexec.c pinq: \ warn-auto.sh pinq.sh conf-qmail conf-break conf-split @@ -1405,17 +1488,17 @@ qldap-debug.o qldap-errno.o auto_break.o qldap.o: \ compile qldap.c qldap.h alloc.h byte.h case.h check.h control.h error.h \ fmt.h qldap-debug.h qldap-errno.h qmail-ldap.h scan.h str.h stralloc.h - ./compile $(LDAPFLAGS) $(LDAPINCLUDES) $(DEBUG) qldap.c + ./compile $(LDAPFLAGS) $(LDAPINCLUDES) qldap.c qldap-cluster.o: \ compile qldap-cluster.c qldap-cluster.h constmap.h control.h qldap-debug.h \ stralloc.h - ./compile $(LDAPFLAGS) $(DEBUG) qldap-cluster.c + ./compile $(LDAPFLAGS) qldap-cluster.c qldap-debug.o: \ compile qldap-debug.c output.h stralloc.h substdio.h fmt.h str.h readwrite.h \ error.h qldap-errno.h env.h scan.h qldap-debug.h - ./compile $(LDAPFLAGS) $(DEBUG) qldap-debug.c + ./compile $(LDAPFLAGS) qldap-debug.c qldap-errno.o: \ compile qldap-errno.c qldap-errno.h error.h @@ -1429,7 +1512,7 @@ profile: qldap-profile.o qldap-profile.o: \ compile qldap-profile.c qldap-profile.h qldap-debug.h - ./compile $(INCTAI) $(DEBUG) qldap-profile.c + ./compile $(INCTAI) $(LDAPFLAGS) qldap-profile.c qmail-cdb: \ load qmail-cdb.o getln.a open.a cdbmake.a seek.a case.a \ @@ -1478,16 +1561,18 @@ qmail-control.9 conf-break conf-spawn qmail-forward: \ load qmail-forward.o qmail.o control.o now.o env.a fd.a wait.a open.a getln.a \ -seek.a stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o +seek.a stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o \ +$(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-forward qmail.o control.o now.o env.a fd.a wait.a \ open.a getln.a seek.a strerr.a stralloc.a alloc.a substdio.a \ - error.a str.a fs.a auto_qmail.o - + error.a $(QLDAPLIB) $(CONTROLLIBS) str.a fs.a auto_qmail.o \ + $(SECUREBINDLIBS) $(LDAPLIBS) + qmail-forward.o: \ compile qmail-forward.c auto_qmail.h control.h error.h fmt.h getln.h now.h \ qmail.h seek.h str.h stralloc.h strerr.h substdio.h ./compile $(LDAPFLAGS) qmail-forward.c - + qmail-getpw: \ load qmail-getpw.o case.a substdio.a error.a str.a fs.a auto_break.o \ auto_usera.o @@ -1514,10 +1599,10 @@ qlx.h qmail-group: \ load qmail-group.o qmail.o now.o control.o case.a getln.a sig.a open.a \ -seek.a fd.a wait.a env.a qldap.a read-ctrl.o stralloc.a alloc.a strerr.a \ +seek.a fd.a wait.a env.a $(QLDAPLIB) read-ctrl.o stralloc.a alloc.a strerr.a \ substdio.a error.a fs.a str.a coe.o auto_qmail.o ./load qmail-group qmail.o now.o control.o case.a getln.a sig.a \ - open.a seek.a fd.a wait.a env.a qldap.a read-ctrl.o stralloc.a \ + open.a seek.a fd.a wait.a env.a $(QLDAPLIB) read-ctrl.o stralloc.a \ alloc.a fs.a strerr.a substdio.a error.a str.a coe.o auto_qmail.o \ $(LDAPLIBS) @@ -1550,12 +1635,14 @@ qmail-inject: \ load qmail-inject.o headerbody.o hfield.o newfield.o quote.o now.o \ control.o date822fmt.o constmap.o qmail.o case.a fd.a wait.a open.a \ getln.a sig.a getopt.a datetime.a token822.o env.a stralloc.a alloc.a \ -substdio.a error.a str.a fs.a auto_qmail.o +substdio.a error.a str.a fs.a auto_qmail.o $(SECUREBINDLIBS) $(QLDAPLIB) \ +$(CONTROLLIBS) ./load qmail-inject headerbody.o hfield.o newfield.o \ quote.o now.o control.o date822fmt.o constmap.o qmail.o \ case.a fd.a wait.a open.a getln.a sig.a getopt.a datetime.a \ token822.o env.a stralloc.a alloc.a substdio.a error.a \ - str.a fs.a auto_qmail.o + $(QLDAPLIB) $(CONTROLLIBS) str.a fs.a auto_qmail.o \ + $(SECUREBINDLIBS) $(LDAPLIBS) qmail-inject.0: \ qmail-inject.8 @@ -1567,7 +1654,7 @@ subfd.h substdio.h sgetopt.h subgetopt.h hfield.h token822.h gen_alloc.h control.h env.h gen_alloc.h \ gen_allocdefs.h error.h qmail.h substdio.h now.h datetime.h exit.h \ quote.h headerbody.h auto_qmail.h newfield.h stralloc.h constmap.h - ./compile qmail-inject.c + ./compile $(LDAPFLAGS) qmail-inject.c qmail-limits.0: \ qmail-limits.7 @@ -1610,13 +1697,26 @@ qmail-log.0: \ qmail-log.5 nroff -man qmail-log.5 > qmail-log.0 +qmail-ldapctrld: \ +load qmail-ldapctrld.o $(QLDAPLIB) getopt.a substdio.a error.a \ +str.a fs.a fd.a env.a read-ctrl.o control.o stralloc.a auto_qmail.o \ +alloc.a case.a getln.a open.a substdio.a + ./load qmail-ldapctrld $(QLDAPLIB) read-ctrl.o control.o \ + getopt.a substdio.a fd.a env.a error.a getln.a stralloc.a \ + alloc.a case.a open.a fs.a substdio.a str.a auto_qmail.o \ + $(LDAPLIBS) + +qmail-ldapctrld.o: \ +compile qmail-ldapctrld.c fork.h byte.h + ./compile $(LDAPFLAGS) -DUSE_CTRLD qmail-ldapctrld.c + qmail-ldaplookup: \ -load qmail-ldaplookup.o qldap.a passwd.o digest_md4.o digest_md5.o \ +load qmail-ldaplookup.o $(QLDAPLIB) passwd.o digest_md4.o digest_md5.o \ digest_rmd160.o digest_sha1.o base64.o constmap.o localdelivery.o \ dirmaker.o wait.a read-ctrl.o control.o env.a getopt.a getln.a stralloc.a \ alloc.a strerr.a error.a substdio.a open.a fs.a str.a case.a auto_usera.o \ auto_qmail.o - ./load qmail-ldaplookup qldap.a passwd.o digest_md4.o digest_md5.o \ + ./load qmail-ldaplookup $(QLDAPLIB) passwd.o digest_md4.o digest_md5.o \ digest_rmd160.o digest_sha1.o base64.o constmap.o localdelivery.o \ dirmaker.o wait.a read-ctrl.o control.o env.a getopt.a getln.a \ stralloc.a alloc.a strerr.a error.a substdio.a open.a fs.a str.a \ @@ -1627,20 +1727,19 @@ compile qmail-ldaplookup.c alloc.h auto_ localdelivery.h output.h passwd.h qldap.h qldap-cluster.h qldap-debug.h \ qldap-errno.h qmail-ldap.h read-ctrl.h scan.h sgetopt.h str.h stralloc.h \ strerr.h subfd.h substdio.h dirmaker.h - ./compile $(LDAPFLAGS) $(SHADOWOPTS) $(HDIRMAKE) $(DEBUG) \ - qmail-ldaplookup.c + ./compile $(LDAPFLAGS) $(SHADOWOPTS) $(HDIRMAKE) qmail-ldaplookup.c qmail-lspawn: \ load qmail-lspawn.o spawn.o prot.o slurpclose.o coe.o control.o \ sig.a strerr.a getln.a wait.a case.a cdb.a fd.a open.a stralloc.a \ alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_uids.o \ -auto_spawn.o auto_usera.o env.a qldap.a dirmaker.o read-ctrl.o \ -localdelivery.o seek.a constmap.o +auto_spawn.o auto_usera.o env.a $(QLDAPLIB) dirmaker.o read-ctrl.o \ +localdelivery.o seek.a constmap.o $(SECUREBINDLIBS) ./load qmail-lspawn spawn.o prot.o slurpclose.o coe.o control.o \ - qldap.a sig.a strerr.a constmap.o getln.a wait.a case.a cdb.a \ + $(QLDAPLIB) sig.a strerr.a constmap.o getln.a wait.a case.a cdb.a \ fd.a seek.a open.a dirmaker.o read-ctrl.o localdelivery.o env.a \ stralloc.a alloc.a substdio.a str.a error.a fs.a auto_qmail.o \ - auto_uids.o auto_usera.o auto_spawn.o $(LDAPLIBS) + auto_uids.o auto_usera.o auto_spawn.o $(SECUREBINDLIBS) $(LDAPLIBS) qmail-lspawn.0: \ qmail-lspawn.8 @@ -1653,15 +1752,16 @@ slurpclose.h auto_qmail.h auto_uids.h ql auto_break.h auto_usera.h byte.h check.h env.h fmt.h localdelivery.h \ open.h qldap.h qldap-debug.h qldap-errno.h qmail-ldap.h read-ctrl.h \ sig.h str.h qldap-cluster.h getln.h seek.h dirmaker.h - ./compile $(LDAPFLAGS) $(HDIRMAKE) $(LDAPINCLUDES) $(DEBUG) \ - qmail-lspawn.c + ./compile $(LDAPFLAGS) $(HDIRMAKE) $(LDAPINCLUDES) qmail-lspawn.c qmail-newmrh: \ load qmail-newmrh.o getln.a open.a cdbmake.a seek.a case.a \ -stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o +stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o \ +$(NEWLDAPPROGLIBS) $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-newmrh getln.a open.a cdbmake.a seek.a \ case.a stralloc.a alloc.a strerr.a substdio.a error.a \ - str.a auto_qmail.o + $(QLDAPLIB) $(CONTROLLIBS) str.a auto_qmail.o \ + $(NEWLDAPPROGLIBS) $(SECUREBINDLIBS) $(LDAPLIBS) qmail-newmrh.0: \ qmail-newmrh.8 @@ -1679,7 +1779,7 @@ qmail-newmrh.o: \ compile qmail-newmrh.c strerr.h stralloc.h gen_alloc.h substdio.h \ getln.h exit.h readwrite.h open.h auto_qmail.h cdb_make.h uint32.h \ substdio.h - ./compile qmail-newmrh.c + ./compile $(LDAPFLAGS) qmail-newmrh.c qmail-newu: \ load qmail-newu.o getln.a open.a seek.a cdbmake.a case.a \ @@ -1764,15 +1864,16 @@ qmail-popup.o: \ compile qmail-popup.c commands.h fd.h sig.h stralloc.h gen_alloc.h \ substdio.h alloc.h wait.h str.h byte.h now.h datetime.h fmt.h exit.h \ readwrite.h timeoutread.h timeoutwrite.h - ./compile $(DEBUG) qmail-popup.c + ./compile $(LDAPFLAGS) qmail-popup.c qmail-pw2u: \ load qmail-pw2u.o constmap.o control.o open.a getln.a case.a getopt.a \ stralloc.a alloc.a substdio.a error.a str.a fs.a auto_usera.o \ -auto_break.o auto_qmail.o +auto_break.o auto_qmail.o $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-pw2u constmap.o control.o open.a getln.a \ - case.a getopt.a stralloc.a alloc.a substdio.a error.a str.a \ - fs.a auto_usera.o auto_break.o auto_qmail.o + case.a getopt.a stralloc.a alloc.a substdio.a error.a \ + $(QLDAPLIB) $(CONTROLLIBS) str.a fs.a auto_usera.o \ + auto_qmail.o $(SECUREBINDLIBS) $(LDAPLIBS) qmail-pw2u.0: \ qmail-pw2u.8 @@ -1791,18 +1892,19 @@ compile qmail-pw2u.c substdio.h readwrit sgetopt.h subgetopt.h control.h constmap.h stralloc.h gen_alloc.h \ fmt.h str.h scan.h open.h error.h getln.h auto_break.h auto_qmail.h \ auto_usera.h - ./compile qmail-pw2u.c + ./compile $(LDAPFLAGS) qmail-pw2u.c qmail-qmqpc: \ load qmail-qmqpc.o slurpclose.o timeoutread.o timeoutwrite.o \ timeoutconn.o ip.o control.o auto_qmail.o sig.a ndelay.a open.a \ getln.a substdio.a stralloc.a alloc.a error.a str.a fs.a socket.lib \ -dns.lib +dns.lib $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-qmqpc slurpclose.o timeoutread.o \ timeoutwrite.o timeoutconn.o ip.o control.o auto_qmail.o \ sig.a ndelay.a open.a getln.a substdio.a stralloc.a alloc.a \ - error.a fs.a dns.o str.a ipalloc.o `cat dns.lib` `cat socket.lib` \ - $(ZLIB) + error.a fs.a dns.o $(QLDAPLIB) $(CONTROLLIBS) str.a \ + ipalloc.o `cat dns.lib` `cat socket.lib` $(ZLIB) \ + $(SECUREBINDLIBS) $(LDAPLIBS) qmail-qmqpc.0: \ qmail-qmqpc.8 @@ -1841,11 +1943,14 @@ qmail-qmtpd: \ load qmail-qmtpd.o rcpthosts.o control.o constmap.o received.o \ date822fmt.o now.o qmail.o cdb.a fd.a seek.a wait.a datetime.a \ open.a getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a \ -error.a str.a fs.a auto_qmail.o +error.a str.a fs.a auto_qmail.o $(SECUREBINDLIBS) $(QLDAPLIB) \ +$(CONTROLLIBS) ./load qmail-qmtpd rcpthosts.o control.o constmap.o \ received.o date822fmt.o now.o qmail.o cdb.a fd.a seek.a \ wait.a datetime.a open.a getln.a sig.a case.a env.a \ - stralloc.a alloc.a substdio.a error.a str.a fs.a auto_qmail.o + stralloc.a alloc.a substdio.a error.a $(QLDAPLIB) \ + $(CONTROLLIBS) str.a fs.a auto_qmail.o $(SECUREBINDLIBS) \ + $(LDAPLIBS) qmail-qmtpd.0: \ qmail-qmtpd.8 @@ -1855,7 +1960,7 @@ qmail-qmtpd.o: \ compile qmail-qmtpd.c stralloc.h gen_alloc.h substdio.h qmail.h \ substdio.h now.h datetime.h str.h fmt.h env.h sig.h rcpthosts.h \ auto_qmail.h readwrite.h control.h received.h - ./compile qmail-qmtpd.c + ./compile $(LDAPFLAGS) qmail-qmtpd.c qmail-qread: \ load qmail-qread.o fmtqfn.o readsubdir.o date822fmt.o datetime.a \ @@ -1893,11 +1998,12 @@ qmail-queue: \ load qmail-queue.o triggerpull.o fmtqfn.o now.o date822fmt.o \ datetime.a seek.a ndelay.a open.a sig.a alloc.a substdio.a error.a \ str.a fs.a auto_qmail.o auto_split.o auto_uids.o control.o constmap.o \ -stralloc.a case.a getln.a +stralloc.a case.a getln.a $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-queue triggerpull.o fmtqfn.o now.o control.o \ constmap.o date822fmt.o datetime.a seek.a ndelay.a open.a sig.a \ - stralloc.a getln.a case.a alloc.a substdio.a error.a str.a fs.a \ - auto_qmail.o auto_split.o auto_uids.o + stralloc.a getln.a case.a alloc.a substdio.a error.a \ + $(QLDAPLIB) $(CONTROLLIBS) str.a fs.a auto_qmail.o \ + auto_split.o auto_uids.o $(SECUREBINDLIBS) $(LDAPLIBS) qmail-queue.0: \ qmail-queue.8 @@ -1913,31 +2019,33 @@ qmail-quotawarn: \ load qmail-quotawarn.o newfield.o now.o date822fmt.o mailmagic.o case.a \ control.o fd.a wait.a open.a myctime.o case.a getln.a sig.a open.a seek.a \ lock.a datetime.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \ -fs.a auto_qmail.o +fs.a auto_qmail.o $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-quotawarn newfield.o now.o date822fmt.o mailmagic.o \ case.a control.o fd.a wait.a open.a myctime.o case.a getln.a sig.a \ open.a seek.a lock.a datetime.a env.a stralloc.a alloc.a strerr.a \ - substdio.a error.a str.a fs.a auto_qmail.o + substdio.a error.a $(QLDAPLIB) $(CONTROLLIBS) str.a fs.a auto_qmail.o \ + $(SECUREBINDLIBS) $(LDAPLIBS) qmail-quotawarn.o: \ compile qmail-quotawarn.c auto_qmail.h byte.h case.h control.h date822fmt.h \ datetime.h env.h error.h exit.h fmt.h getln.h mailmagic.h myctime.h \ newfield.h now.h open.h qmail-ldap.h seek.h sig.h str.h strerr.h substdio.h \ wait.h lock.h - ./compile qmail-quotawarn.c + ./compile $(LDAPFLAGS) qmail-quotawarn.c qmail-remote: \ load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \ timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o xtext.o \ base64.o ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a \ alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o \ -dns.lib socket.lib +dns.lib socket.lib $(QLDAPLIB) $(CONTROLLIBS) $(SECUREBINDLIBS) ./load qmail-remote control.o constmap.o timeoutread.o \ timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \ ipalloc.o ipme.o quote.o xtext.o base64.o ndelay.a case.a \ sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \ - strerr.a substdio.a error.a str.a fs.a auto_qmail.o \ - `cat dns.lib` `cat socket.lib` $(TLSLIBS) $(ZLIB) + strerr.a substdio.a error.a $(QLDAPLIB) $(CONTROLLIBS) \ + str.a fs.a auto_qmail.o $(SECUREBINDLIBS) `cat dns.lib` \ + `cat socket.lib` $(TLSLIBS) $(ZLIB) $(LDAPLIBS) qmail-remote.0: \ qmail-remote.8 @@ -1956,11 +2064,14 @@ qmail-reply: \ load qmail-reply.o mailmagic.o case.a control.o constmap.o getln.a \ sig.a newfield.o now.o date822fmt.o datetime.a open.a seek.a env.a \ qmail.o getopt.a fd.a wait.a digest_md5.o base64.o stralloc.a alloc.a \ -strerr.a substdio.a error.a str.a fs.a auto_qmail.o +strerr.a substdio.a error.a str.a fs.a auto_qmail.o $(SECUREBINDLIBS) \ +$(QLDAPLIB) $(CONTROLLIBS) ./load qmail-reply mailmagic.o case.a control.o constmap.o \ getln.a sig.a newfield.o now.o date822fmt.o datetime.a open.a \ seek.a env.a qmail.o getopt.a fd.a wait.a digest_md5.o base64.o \ - stralloc.a alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o + stralloc.a alloc.a strerr.a substdio.a error.a $(QLDAPLIB) \ + $(CONTROLLIBS) str.a fs.a auto_qmail.o $(SECUREBINDLIBS) \ + $(LDAPLIBS) qmail-reply.o: \ compile qmail-reply.c byte.h case.h control.h constmap.h direntry.h env.h \ @@ -1990,12 +2101,14 @@ qmail-secretary: \ load qmail-secretary.o base64.o digest_sha1.o control.o newfield.o now.o \ date822fmt.o datetime.a mailmaker.o mailmagic.o case.a getln.a qmail.o \ quote.o getopt.a seek.a fd.a wait.a sig.a open.a stralloc.a env.a alloc.a \ -strerr.a substdio.a error.a str.a fs.a auto_qmail.o +strerr.a substdio.a error.a str.a fs.a auto_qmail.o $(SECUREBINDLIBS) $(QLDAPLIB) \ +$(CONTROLLIBS) ./load qmail-secretary base64.o digest_sha1.o control.o newfield.o \ now.o date822fmt.o datetime.a mailmaker.o mailmagic.o case.a getln.a \ qmail.o quote.o getopt.a seek.a fd.a wait.a sig.a open.a stralloc.a \ - env.a alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o - + env.a alloc.a strerr.a substdio.a error.a $(QLDAPLIB) $(CONTROLLIBS) \ + str.a fs.a auto_qmail.o $(SECUREBINDLIBS) $(LDAPLIBS) + qmail-secretary.o: \ compile qmail-secretary.c uint32.h base64.h byte.h case.h digest_sha1.h \ direntry.h env.h error.h fd.h fmt.h getln.h mailmagic.h newfield.h now.h \ @@ -2008,12 +2121,14 @@ load qmail-send.o qsutil.o control.o con trigger.o fmtqfn.o quote.o now.o readsubdir.o qmail.o date822fmt.o \ datetime.a case.a ndelay.a getln.a wait.a cdb.a seek.a fd.a sig.a \ open.a lock.a stralloc.a env.a alloc.a substdio.a error.a str.a fs.a \ -auto_qmail.o auto_split.o +auto_qmail.o auto_split.o $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-send qsutil.o control.o constmap.o newfield.o \ prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \ qmail.o date822fmt.o datetime.a case.a ndelay.a getln.a \ wait.a cdb.a seek.a fd.a sig.a open.a lock.a stralloc.a env.a \ - alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_split.o + alloc.a substdio.a error.a $(QLDAPLIB) $(CONTROLLIBS) \ + str.a fs.a auto_qmail.o auto_split.o $(SECUREBINDLIBS) \ + $(LDAPLIBS) qmail-send.0: \ qmail-send.8 @@ -2039,11 +2154,12 @@ fmtqfn.h readsubdir.h direntry.h cdb.h u qmail-showctl: \ load qmail-showctl.o auto_uids.o control.o open.a getln.a stralloc.a \ alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_break.o \ -auto_patrn.o auto_spawn.o auto_split.o +auto_patrn.o auto_spawn.o auto_split.o $(SECUREBINDLIBS) $(QLDAPLIB) \ +$(CONTROLLIBS) ./load qmail-showctl auto_uids.o control.o open.a getln.a \ - stralloc.a alloc.a substdio.a error.a str.a fs.a \ - auto_qmail.o auto_break.o auto_patrn.o auto_spawn.o \ - auto_split.o + stralloc.a alloc.a substdio.a error.a $(QLDAPLIB) \ + $(CONTROLLIBS) str.a fs.a auto_qmail.o auto_patrn.o \ + auto_spawn.o auto_split.o $(SECUREBINDLIBS) $(LDAPLIBS) qmail-showctl.0: \ qmail-showctl.8 @@ -2054,7 +2170,7 @@ compile qmail-showctl.c substdio.h subfd str.h control.h constmap.h stralloc.h gen_alloc.h direntry.h \ auto_uids.h auto_qmail.h auto_break.h auto_patrn.h auto_spawn.h \ auto_split.h - ./compile qmail-showctl.c + ./compile $(LDAPFLAGS) qmail-showctl.c qmail-smtpd: \ load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o rbl.o \ @@ -2062,14 +2178,15 @@ timeoutwrite.o ip.o ipme.o ipalloc.o con 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 str.a fs.a auto_qmail.o auto_break.o \ -dns.lib socket.lib +dns.lib socket.lib $(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o rbl.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ 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 $(QLDAPLIB) str.a \ + `cat dns.lib` `cat socket.lib` $(TLSLIBS) $(ZLIB) \ + $(SECUREBINDLIBS) $(LDAPLIBS) read-ctrl.o qmail-smtpd.0: \ qmail-smtpd.8 @@ -2145,10 +2262,12 @@ fmt.h ip.h lock.h error.h exit.h datetim qmail-todo: \ load qmail-todo.o control.o constmap.o trigger.o fmtqfn.o now.o \ readsubdir.o case.a ndelay.a getln.a sig.a cdb.a open.a stralloc.a \ -alloc.a substdio.a error.a str.a seek.a fs.a auto_qmail.o auto_split.o +alloc.a substdio.a error.a str.a seek.a fs.a auto_qmail.o auto_split.o \ +$(SECUREBINDLIBS) $(QLDAPLIB) $(CONTROLLIBS) ./load qmail-todo control.o constmap.o trigger.o fmtqfn.o now.o \ readsubdir.o case.a ndelay.a getln.a sig.a cdb.a open.a stralloc.a \ - alloc.a substdio.a error.a str.a seek.a fs.a auto_qmail.o auto_split.o + alloc.a substdio.a error.a $(QLDAPLIB) $(CONTROLLIBS) str.a seek.a \ + fs.a auto_qmail.o auto_split.o $(SECUREBINDLIBS) $(LDAPLIBS) qmail-todo.o: \ compile qmail-todo.c alloc.h auto_qmail.h byte.h cdb.h constmap.h control.h \ @@ -2180,8 +2299,8 @@ qmail-users.9 conf-break conf-spawn qmail-verify: \ load qmail-verify.o qldap.a read-ctrl.o control.o getln.a substdio.a \ stralloc.a env.a alloc.a error.a open.a fs.a case.a cdb.a str.a timeoutread.o \ -localdelivery.o auto_qmail.o - ./load qmail-verify qldap.a read-ctrl.o control.o getln.a \ +localdelivery.o auto_qmail.o $(QLDAPLIB) + ./load qmail-verify $(QLDAPLIB) qldap.a read-ctrl.o control.o getln.a \ substdio.a stralloc.a env.a alloc.a error.a open.a fs.a case.a \ cdb.a str.a seek.a timeoutread.o localdelivery.o auto_qmail.o \ $(LDAPLIBS) @@ -2484,7 +2603,7 @@ compile chkspawn spawn.c sig.h wait.h su stralloc.h gen_alloc.h select.h exit.h coe.h open.h error.h \ auto_qmail.h auto_uids.h auto_spawn.h ./chkspawn - ./compile $(DEBUG) spawn.c + ./compile $(LDAPFLAGS) spawn.c splogger: \ load splogger.o substdio.a error.a str.a fs.a syslog.lib socket.lib Index: qmail-1.03/QLDAPINSTALL =================================================================== --- qmail-1.03.orig/QLDAPINSTALL +++ qmail-1.03/QLDAPINSTALL @@ -127,6 +127,38 @@ INSTALL: see also 10.) - TLS* stuff for TLS (SMTP encryption) mostly self explaining + The following compile flags are availible if adding the QmailLDAP/Controls patch. + - RFCFLAGS + -DUSE_RFC2307 + Lets you have the whole user/group/host etc system in the LDAP db, + without duplicating information (qmailUID -> uidNumber etc). See + below for changes in the LDIF format. + + -DUSE_RFC822 + The differences are that while the default QmailLDAP behaviour + uses the following attributes + mail Store the mail address + mailForwardingAddress Where to send mail + + The RFC822 says to use the following attributes instead: + mailLocalAddress Store the mail address + mailRoutingAddress Where to send mail + + The attribute 'mailHost' are uses in both objectclasses. + The objectclass for this RFC are 'inetLocalMailRecipient' instead + of 'homemade'. This I-D has, however, expired. Use with extreme care. + + These are not really necessary any more, you can change qmail-ldap.h + instead. It's just here because I like a simple Makefile define to + have it according to the RFC's... + + - CONTROLDB=-DUSE_CONTROLDB + Lets you have all the control information in the same LDAP database + as the user db (OR, depending on how you set up the database entries + for the control section, having the control database in one place, and + the users in another database). Control entries are only read when + starting QMail (or when sending a SIGHUP to the qmail-lspawn process). + 5.1 Have a look at qmail-ldap.h, perhaps you want to change something there. LDAP_CATCH_ALL: used for catching mails for a specific domain. Also used for extension nameing with DASH_EXT. @@ -180,8 +212,19 @@ INSTALL: certificates 7. Create the LDAP user database and start the LDAP server + This is of course not necessary if you used the MigrationTools from + the OpenLDAP site to create a user/group/hosts db. You should however + Take a look at what extra LDAP parameter fields that you want to use, + and add those to your database. The script 'ldapcfg.sh' can/should be + used for this. Oki, so this script isn't quite done yet, but it SHOULD + be used for this when it's ready :) See point 7.1 below... + See qmail.schema for definition of all fields for OpenLDAP 2.x +7.1 If you compiled with -DUSE_CONTROLDB you have to create the appropriate + qmail control database (ether from scratch, or by moving your existing + information into the database). + 8. Create the proper ~control/ldap* files for qmail-ldap At least ldapserver and ldapbasedn must exist (and also 'me') @@ -293,6 +336,56 @@ OR ldap2.nrg4u.com ldap3.nrg4u.com:1234 +~control/ldapcontroldn + + The base DN for where the control information is stored + Default: NULL + Example: ou=QmailLDAP,o=Internet Pipeline,c=CH + Note: Referrals are ignored (for now :) + +~control/port_ldap + + The port to the ldapserver, if not specified in ~control/ldapserver. + Global value -> affects ALL LDAP servers defined. If not specified, + default is used. + Default: 389 + Example: 636 + +~control/port_qmqp + + This is the port the QMQP server should use. If not specified, default is used. + Default: 628 + Example: 2345 + +~control/port_smtp + + This is the port the SMTP server should bind to. If not specified, default is used. + Default: 25 + Example: 465 + +~control/port_imap + + This is the port the IMAP server should connect to when forwarding connection. If + not specified, default is used. + Default: 143 + Example: 342 + +~control/port_pop3 + + This is the port the POP3 server should connect to when forwarding connection. If + not specified, default is used. + Default: 110 + Example: 818 + +~control/ldapsecurebind + + This is the commandline options we can use to control the connection to the LDAP + server with. The options are duplicates of those used with OpenLDAP's command + ldapsearch. Options are specified on one line, one by one, separated by space. + Default: NULL, SSL/TLS/SASL not used + Example: -U turbo -R BAYOUR.COM -Z + Note: See the QLDAPNEWS file for more information about availible options. + ~control/ldapbasedn The base DN from where the search in the LDAP tree begins @@ -1207,7 +1300,7 @@ LDAP_QMAILUSER (default: "qmailUser") ================================================================================ -EXAMPLE QLDAP LDIF FILE: +EXAMPLE QLDAP LDIF FILE (without the RFC2307 option): dn: cn=Andre Oppermann, o=Internet Pipeline, c=CH objectClass: top @@ -1231,6 +1324,45 @@ uid: opi userPassword: {SMD5}b28a87511da157f147ed4766b0474a8a accountStatus: active +EXAMPLE QLDAP LDIF FILE (with the RFC2307 option): + +dn: cn=Andre Oppermann, o=Internet Pipeline, c=CH +cn: Andre Oppermann +sn: Oppermann +objectClass: top +objectClass: person +objectClass: inetOrgPerson +objectClass: mailRecipient +mail: opi@opi.flirtbox.ch +mailHost: opi.flirtbox.ch +homeDirectory: /usr/home/opi/maildir/ +mailQuotaSize: 1000000 +mailQuotaCount: 1000 +uidNumber: 1001 +gidNumber: 1001 +uid: opi +userPassword: {SMD5}b28a87511da157f147ed4766b0474a8a + +EXAMPLE QMAIL/QLDAP CONTROL LDIF FILE: +dn: cn=mail.pipeline.ch,ou=QmailLDAP, o=Internet Pipeline, c=CH +cn: mail.pipeline.ch +objectClass: top +objectClass: qmailControl +locals: pipeline.ch +rcptHosts: pipeline.ch +ldapDefaultQuota: 1000 +defaultDomain: pipeline.ch +ldapDefaultDotMode: both +ldapRebind: 1 +dirMaker: /usr/local/bin/mkhome +ldapBaseDN: ou=Users, o=Internet Pipeline, c=CH + +The 'cn=' entry is the FQDN (Fully Qualified Domain Name, ie the full +hostname+domainname) of the host qmail is running on. We sort the +entries under each 'cn=,' in our database so that we +can have multiple configurations for multiple qmail servers in the +same database under the same branch. + ================================================================================ EXAMPLE SLAPD.CONF FILE: @@ -1252,6 +1384,11 @@ include ./schema/nis.schema #include ./schema/inetorgperson.schema include ./schema/qmail.schema +# If using the QmailLDAP/Controls patch, copy the qmailControl.schema to +# your OpenLDAP installation location and remove the comment for the +# include line. +#include ./qmailControl.schema + # tuneing schemacheck on idletimeout 60 Index: qmail-1.03/QLDAPNEWS =================================================================== --- qmail-1.03.orig/QLDAPNEWS +++ qmail-1.03/QLDAPNEWS @@ -15,6 +15,65 @@ TODO: WARNING: If you are upgrading from 20030801a or earlier make sure that you have read the news section for 20030901. +Patch by Turbo Fredriksson (QmailLDAP/Controls): + * http://qmail.bayour.com/patches_ldap/ + * If no '~control/ldapserver' file could be found, fallback to default + "localhost". + * Removed the PORT_QMQP and PORT_SMTP defines. Can now be overridden + by creating the file ~control/qmqpport and ~control/smtpport. + * Having the whole system (ie, users/groups/hosts etc) in the db, and + have that as a login db duplicates a lot of info (qmailUID -> + uidNumber etc). The default usage for the QMailLDAP patch is to only + have the mail system (mailaddress and delivery path). Many with me + like to have all the users information (for use as login system etc) + in the LDAP database. So having the option to use LDAP as database + for users are configured in the Makefile (the RFC2307 option). This + can of course be changed in the file 'qmail-ldap.h', but I wanted a + easy compile time option to do this. This will be a runtime option, as + soon as I feel like adding that code :). + + These are the changes in keywords: + Original patch Turbo's patch (w/ the RFC2307 option) + qmailUID uidNumber + qmailGID gidNumber + * Support for boolean (TRUE/FALSE) values in the LDAP database. + * Added support for having the control files in a LDAP database. The + only files that are needed are ~control/ldapserver (so that we know + WHAT server to contact) and ~control/ldapcontroldn (so that we know + WHERE in the database the information is located). You also need the + files ~control/ldaplogin and ~control/ldappassword in case your + database is not world readable. See below on LDIF examples etc. Every + other value that QMail/QMail-LDAP needs can now be put in the LDAP + database. + * Added support to have the port in a control file/entry instead of as a + compile time option. Gives you the ability to use the same binary for + your production system AND in a test invironment. + * We can now bind to the LDAP server using SSL, TLS and/or SASL. Ideas + for this code was taken/copied from the OpenLDAP 'ldapsearch' command, + and therefor we can use the following options to qmail when starting + up: + -O + SASL security properties + -Q Enable SASL Quiet mode. + -R + SASL realm + -U + Username for SASL bind. The syntax of the username depends + on the actual SASL mechanism used. + -Y + SASL mechanism to be used for authentication. If it's not + specified, the program will choose the best mechanism the + server knows. + -X + Requested authorization ID for SASL bind. Authzid must be + one of the following formats: + dn: + or + u: + -Z Issue StartTLS (Transport Layer Security) extended operation. + These options are inserted into the ~control/ldapsecurebind file. See + QLDAPINSTALL file for more about this (with examples). + NEWS for current stuff: Rewritten forwarding code in auth_pop and auth_imap. The copyloop is now Index: qmail-1.03/QLDAPTODO =================================================================== --- qmail-1.03.orig/QLDAPTODO +++ qmail-1.03/QLDAPTODO @@ -16,9 +16,9 @@ TODO: ongoing - Debugging and testing, testing, testing done - The big qmail-ldap picture ongoing - full code review by a third person -planned - make it possible to have locals and rcpthosts in ldap - and perhaps also the rules for the tcpserver (certs?) - some people refer to this as ldap-control +planned - If a control value (for example 'ldapbasedn') exists + multiple time in the DB (which is not allowed) both of + them is used. PS: planned means we see the use of the idea but there are a lot more important things that need to be done first. Index: qmail-1.03/TARGETS =================================================================== --- qmail-1.03.orig/TARGETS +++ qmail-1.03/TARGETS @@ -460,3 +460,6 @@ read-ctrl.o readwrite.o smtpcall.o xtext.o +qmail-ldapctrld.o +qmail-ldapctrld +qmail-ldapctrld-test Index: qmail-1.03/auth_imap.c =================================================================== --- qmail-1.03.orig/auth_imap.c +++ qmail-1.03/auth_imap.c @@ -58,11 +58,31 @@ #include "auth_mod.h" +#ifdef SYSLOGAUTH +#include +#endif + +#ifdef USE_CONTROLDB +#include +#include "qldap.h" +qldap *q; + +static stralloc ldap_me = {0}; +static stralloc ldap_server = {0}; +static stralloc ldap_login = {0}; +static stralloc ldap_password = {0}; +static stralloc ldap_controldn = {0}; + +const char *(auth_file[]) = { "control/port_imap", 0 }; +const char *(auth_port_default[]) = { "143", 0 }; +static stralloc ldap_authport; +unsigned int auth_port; +#else #ifndef PORT_IMAP /* this is for testing purposes */ #define PORT_IMAP 143 #endif - const unsigned int auth_port = PORT_IMAP; +#endif #define UP_LEN 1024 static char auth_up[UP_LEN]; @@ -96,7 +116,7 @@ auth_init(int argc, char **argv, strallo a = env_get("AUTHENTICATED"); if (a && *a) { /* Already a good guy */ - logit(8, "auth_init: allready authenticated\n"); + logit(8, "auth_init: already authenticated\n"); execvp(*argv, argv); auth_error(AUTH_EXEC); } @@ -179,6 +199,10 @@ auth_fail(const char *login, int reason) int pi[2], n; char *t = auth_up; +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication failed (user: %s)", login); + closelog(); +#endif logit(2, "warning: auth_fail: user %s failed\n", login); if (reason == NOSUCH || reason == AUTH_TYPE) { logit(4, "warning: auth_fail: %s\n", qldap_err_str(reason)); @@ -225,6 +249,11 @@ auth_fail(const char *login, int reason) void auth_success(const char *login) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication succeeded (user: %s)", login); + closelog(); +#endif + byte_zero(auth_up, sizeof(auth_up)); /* pop befor smtp */ Index: qmail-1.03/auth_mod.c =================================================================== --- qmail-1.03.orig/auth_mod.c +++ qmail-1.03/auth_mod.c @@ -63,6 +63,16 @@ #include "mailmaker.h" #endif +#ifdef SYSLOGAUTH +#include +#endif + +#ifdef USE_CONTROLDB +stralloc ldap_authport = {0}; +extern const char *auth_file; +extern unsigned int auth_port; +extern const char *auth_port_default; +#endif #include "checkpassword.h" #include "auth_mod.h" @@ -100,10 +110,15 @@ main(int argc, char **argv) struct credentials c; int r; +#ifdef SYSLOGAUTH + openlog(argv[1], LOG_PID, LOG_AUTHPRIV|LOG_MAIL); +#else log_init(STDERR, ~256, 0); /* XXX limited so that it is not possible to get passwords via debug on production systems. */ +#endif + if (read_controls(ctrls) == -1) auth_error(AUTH_CONF); @@ -112,7 +127,11 @@ main(int argc, char **argv) loginstr.s, authdatastr.s); if (authdatastr.len <= 1) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "alert: null password."); +#else logit(1, "alert: null password.\n"); +#endif auth_fail(loginstr.s, BADPASS); } @@ -174,30 +193,56 @@ chdir_or_make(char *home, char *maildir) case OK: break; case MAILDIR_CRASHED: +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: dirmaker failed: program crashed"); +#else logit(2, "warning: dirmaker failed: program crashed\n"); +#endif auth_error(MAILDIR_FAILED); case MAILDIR_FAILED: +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: dirmaker failed: bad exit status"); +#else logit(2, "warning: dirmaker failed: bad exit status\n"); +#endif auth_error(MAILDIR_FAILED); case MAILDIR_UNCONF: +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: dirmaker failed: not configured"); +#else logit(2, "warning: dirmaker failed: not configured\n"); +#endif auth_error(MAILDIR_NONEXIST); case MAILDIR_HARD: +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: dirmaker failed: hard error"); +#else logit(2, "warning: dirmaker failed: hard error\n"); +#endif case ERRNO: default: - logit(2, "warning: dirmaker failed (%s)\n", - error_str(errno)); +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: dirmaker failed (%s)", error_str(errno)); +#else + logit(2, "warning: dirmaker failed (%s)\n", error_str(errno)); +#endif auth_error(MAILDIR_FAILED); } if (chdir(home) == -1) { - logit(2, "warning: 2nd chdir failed: %s\n", - error_str(errno)); +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: 2nd chdir failed: %s\n",error_str(errno)); +#else + logit(2, "warning: 2nd chdir failed: %s\n", error_str(errno)); +#endif auth_error(MAILDIR_FAILED); } logit(32, "homedir successfully made\n"); #else +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: chdir failed: %s", error_str(errno)); +#else logit(2, "warning: chdir failed: %s\n", error_str(errno)); +#endif auth_error(MAILDIR_NONEXIST); #endif } @@ -206,12 +251,20 @@ chdir_or_make(char *home, char *maildir) case OK: break; case MAILDIR_CORRUPT: +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: maildir_make failed (%s)", +#else logit(2, "warning: maildir_make failed (%s)\n", +#endif "maildir seems to be corrupt"); auth_error(MAILDIR_CORRUPT); case ERRNO: default: +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: maildir_make failed (%s)", +#else logit(2, "warning: maildir_make failed (%s)\n", +#endif error_str(errno)); auth_error(MAILDIR_FAILED); } @@ -236,7 +289,12 @@ copyloop(int infdr, int infdw, int outfd outbuf = alloc(COPY_BUF_SIZE); if (inbuf == (char *)0 || outbuf == (char *)0) { - logit(1, "copyloop: %s\n", error_str(errno)); +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "copyloop: %s\n", +#else + logit(1, "copyloop: %s\n", +#endif + error_str(errno)); close(infdr); close(infdw); close(outfd); @@ -265,7 +323,11 @@ copyloop(int infdr, int infdw, int outfd r = select(maxfd, &rfds, &wfds, (fd_set *)0, &tv); if (r == -1) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "copyloop: select %s", +#else logit(1, "copyloop: select: %s\n", +#endif error_str(errno)); break; } else if (r == 0) { @@ -277,7 +339,11 @@ copyloop(int infdr, int infdw, int outfd if ((r = subread(infdr, inbuf + inpos, COPY_BUF_SIZE - inpos)) == -1) { if (errno == error_intr) continue; +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "copyloop: read %s\n", +#else logit(1, "copyloop: read: %s\n", +#endif error_str(errno)); break; } @@ -289,7 +355,11 @@ copyloop(int infdr, int infdw, int outfd if ((r = subread(outfd, outbuf + outpos, COPY_BUF_SIZE - outpos)) == -1) { if (errno == error_intr) continue; +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "copyloop: read: %s\n", +#else logit(1, "copyloop: read: %s\n", +#endif error_str(errno)); break; } @@ -300,7 +370,11 @@ copyloop(int infdr, int infdw, int outfd if (FD_ISSET(infdw, &wfds)) { if ((r = subwrite(infdw, outbuf, outpos)) == -1) { if (errno == error_intr) continue; +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "copyloop: write: %s\n", +#else logit(1, "copyloop: write: %s\n", +#endif error_str(errno)); break; } @@ -311,7 +385,11 @@ copyloop(int infdr, int infdw, int outfd if (FD_ISSET(outfd, &wfds)) { if ((r = subwrite(outfd, inbuf, inpos)) == -1) { if (errno == error_intr) continue; +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "copyloop: write: %s\n", +#else logit(1, "copyloop: write: %s\n", +#endif error_str(errno)); break; } @@ -345,7 +423,9 @@ forward(char *name, char *passwd, struct int ffd; int timeout = 31*60; /* ~30 min timeout RFC1730 */ int ctimeout = 30; - +#ifdef COURIER + char *a; +#endif /* pop befor smtp */ pbsexec(); @@ -378,6 +458,22 @@ forward(char *name, char *passwd, struct if (ffd == -1) auth_error(ERRNO); +#ifdef USE_CONTROLDB + if (control_rldef(&ldap_authport, auth_file, 0, auth_port_default) != -1) { + if (!stralloc_0(&ldap_authport)) + auth_error(AUTH_CONF); + else + auth_port = atoi(ldap_authport.s); + + logit(64, "init_ldap: %s: %S\n", auth_file, ldap_authport); + } +#endif +#ifdef COURIER + a = env_get("PORT"); + if (a && *a) + auth_port = atoi(a); + logit(64, "init_ldap: env(PORT): %d\n", auth_port); +#endif if (timeoutconn(ffd, &ip.ix[0].ip, &outip, auth_port, ctimeout) != 0) auth_error(ERRNO); Index: qmail-1.03/auth_mod.h =================================================================== --- qmail-1.03.orig/auth_mod.h +++ qmail-1.03/auth_mod.h @@ -36,7 +36,11 @@ #include "stralloc.h" +#ifdef USE_CONTROLDB +unsigned int auth_port; +#else extern const unsigned int auth_port; +#endif /* * auth_init must return the 0-terminated strings login and authdata. Index: qmail-1.03/auth_pop.c =================================================================== --- qmail-1.03.orig/auth_pop.c +++ qmail-1.03/auth_pop.c @@ -50,11 +50,32 @@ #include "auth_mod.h" +#ifdef SYSLOGAUTH +#include +#endif + +#ifdef USE_CONTROLDB +#include +#include "qldap.h" +qldap *q; + +static stralloc ldap_me = {0}; +static stralloc ldap_server = {0}; +static stralloc ldap_login = {0}; +static stralloc ldap_password = {0}; +static stralloc ldap_controldn = {0}; + +const char *(auth_file[]) = { "control/port_pop3", 0 }; +const char *(auth_port_default[]) = { "110", 0 }; +static stralloc ldap_authport; +unsigned int auth_port; +#else #ifndef PORT_POP3 /* this is for testing purposes */ #define PORT_POP3 110 #endif const unsigned int auth_port = PORT_POP3; +#endif #define UP_LEN 513 static char auth_up[UP_LEN]; @@ -65,6 +86,10 @@ void auth_init(int argc, char **argv, stralloc *login, stralloc *authdata) { char *l, *p; +#ifdef COURIER + char *a, *s, *t; + int courier = 0; +#endif unsigned int uplen, u; int n, opt; @@ -85,6 +110,13 @@ auth_init(int argc, char **argv, strallo auth_argc = argc; auth_argv = argv; +#ifdef COURIER + a = env_get("POP3AUTH"); + if (a && *a) + /* (hopfully) running from Courier POP3. */ + courier = 1; +#endif + for (uplen = 0;;) { do { n = subread(3, auth_up + uplen, @@ -101,15 +133,66 @@ auth_init(int argc, char **argv, strallo auth_up[uplen++] = '\0'; u = 0; + +#ifdef COURIER + if(courier) { + /* Courier will send a slightly different line for us: + * SERVICE\nAUTHTYPE\nAUTHDATA + * => pop3\nlogin\nfrans\nseCreTPw\n\n + */ + + /* Ignore service field. */ + s = auth_up; + while (auth_up[u] && auth_up[u] != '\n' ) u++; + if (u >= uplen) + auth_error(NEEDED); + auth_up[u++] = '\0'; + + /* Type has to be "login" else fail ... */ + t = auth_up + u; + while (auth_up[u] && auth_up[u] != '\n' ) u++; + if (u >= uplen) + auth_error(NEEDED); + auth_up[u++] = '\0'; + if (str_diff("login", t)) { + /* This modul supports only "login"-type, + * fail with AUTH_TYPE, so the + * next modul is called, perhaps with greater success. + */ + auth_fail("unknown", AUTH_TYPE); + } + + /* next login */ + l = auth_up + u; + while (auth_up[u] && auth_up[u] != '\n' ) u++; + if (u >= uplen) + auth_error(NEEDED); + auth_up[u++] = '\0'; + + /* and the password */ + p = auth_up + u; + while (auth_up[u] && auth_up[u] != '\n' ) u++; + if (u >= uplen) + auth_error(NEEDED); + auth_up[u++] = '\0'; + if (u > uplen) ; /* paranoia */ + } else { +#else l = auth_up; while (auth_up[u++]) ; if (u == uplen) auth_error(NEEDED); + p = auth_up + u; while (auth_up[u++]) ; if (u == uplen) auth_error(NEEDED); +#endif +#ifdef COURIER + } +#endif + /* Copy the login and password into the coresponding structures */ if (!stralloc_copys(login, l)) auth_error(ERRNO); if (!stralloc_0(login)) @@ -127,6 +210,10 @@ auth_init(int argc, char **argv, strallo void auth_fail(const char *login, int reason) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication failed (user: %s)", login); + closelog(); +#endif /* in the qmail-pop3 chain it is not possible to have multiples * authentication modules. So lets exit with the correct number ... */ /* In this case we can use auth_error() */ @@ -137,6 +224,11 @@ auth_fail(const char *login, int reason) void auth_success(const char *login) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication succeeded (user: %s)", login); + closelog(); +#endif + /* pop befor smtp */ pbsexec(); @@ -152,7 +244,11 @@ void auth_error(int errnum) /* * See qmail-popup.c for exit codes meanings. */ +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "warning: auth_error: authorization failed (%s)", +#else logit(2, "warning: auth_error: authorization failed (%s)\n", +#endif qldap_err_str(errnum)); if (errnum == AUTH_CONF) _exit(1); Index: qmail-1.03/auth_smtp.c =================================================================== --- qmail-1.03.orig/auth_smtp.c +++ qmail-1.03/auth_smtp.c @@ -63,6 +63,27 @@ checkfunc cfuncs[] = { stralloc line = {0}; stralloc plain = {0}; +#ifdef SYSLOGAUTH +#include +#endif + +#ifdef USE_CONTROLDB +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#define AUTH_FILE "control/port_smtp" +unsigned int auth_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif +#endif + void auth_init(int argc, char **argv, stralloc *login, stralloc *authdata) { @@ -119,6 +140,10 @@ auth_init(int argc, char **argv, strallo void auth_fail(const char *login, int reason) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication failed (user: %s)", login); + closelog(); +#endif logit(2, "warning: auth_fail: user %s failed\n", login); if (substdio_putflush(subfdout, "D", 1) == -1) auth_error(ERRNO); @@ -128,6 +153,11 @@ auth_fail(const char *login, int reason) void auth_success(const char *login) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication succeeded (user: %s)", login); + closelog(); +#endif + if (substdio_put(subfdout, "K", 1) == -1) auth_error(ERRNO); if (substdio_puts(subfdout, login) == -1) auth_error(ERRNO); if (substdio_putflush(subfdout, "", 1) == -1) auth_error(ERRNO); @@ -136,6 +166,10 @@ auth_success(const char *login) void auth_error(int errnum) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authorization failed (%s)", qldap_err_str(errnum)); + closelog(); +#endif logit(2, "warning: auth_error: authorization failed (%s)\n", qldap_err_str(errnum)); if (errnum == BADVAL || errnum == NEEDED || errnum == ILLVAL) { @@ -179,6 +213,10 @@ main(int argc, char **argv) loginstr.s, authdatastr.s); if (authdatastr.len <= 1) { +#ifdef SYSLOGAUTH + syslog(LOG_AUTHPRIV|LOG_DEBUG, "authentication failed - null password"); + closelog(); +#endif logit(1, "alert: null password.\n"); auth_fail(loginstr.s, BADPASS); } Index: qmail-1.03/checkpassword.c =================================================================== --- qmail-1.03.orig/checkpassword.c +++ qmail-1.03/checkpassword.c @@ -218,12 +218,16 @@ check_ldap(stralloc *login, stralloc *au } logit(32, "check_ldap: password compare was %s\n", pwok == OK?"successful":"not successful"); +#ifndef USE_CONTROLDB qldap_free(q); +#endif if (pwok == OK && needforward == 1) return FORWARD; return pwok; fail: +#ifndef USE_CONTROLDB qldap_free(q); +#endif return r; } @@ -266,9 +270,11 @@ setup_env(char *user, struct credentials if (!env_put2("USER", user)) auth_error(ERRNO); - /* only courier-imap needs this but we set it anyway */ + /* only courier-imap needs these, but we set it anyway */ if (!env_put2("AUTHENTICATED", user)) auth_error(ERRNO); + if (!env_put2("AUTHADDR", user)) + auth_error(ERRNO); if (c->home.s != 0 && c->home.len > 0) if (!env_put2("HOME", c->home.s)) Index: qmail-1.03/control.c =================================================================== --- qmail-1.03.orig/control.c +++ qmail-1.03/control.c @@ -10,6 +10,64 @@ #include "scan.h" #include "limit.h" +#if defined(USE_CONTROLDB) || defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#include +#endif + +#ifdef USE_CONTROLDB +#include + +/* Include some LDAP magic... */ +#include +#include +#include "qmail-ldap.h" +#include "qldap-debug.h" +#include "qldap-errno.h" +#include "qlx.h" +#include "qldap.h" + +extern qldap *q; + +/* These are defined in every (!!) file that tries to open a file + * in ~control/. */ +extern stralloc ldap_me; +extern stralloc ldap_server; +extern stralloc ldap_controldn; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_basedn; +extern stralloc ldap_port; + + +/* This is the function that searches the ControlDN for the correct + * information. The information that was previously in files. + * + * See the end of this file for this function. */ +int control_ldap_search(const char *fn, stralloc *sa, int flagme, int multvalues); +#endif + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#include +#include +#include + +#include "subfd.h" +#include "sgetopt.h" + +extern int use_tls; +extern int use_ssl; +extern int use_uri; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_ALL) +static unsigned sasl_flags = LDAP_SASL_AUTOMATIC; +#endif + +void qldap_getcontrols_securebind(char *securebind); +int string2argv(char **out, char *in); +int verify_ldap_file_check(const char *fn); +char *flatten_attrib_array(const char *attrs[]); +#endif + static char inbuf[64]; static stralloc line = {0}; static stralloc me = {0}; @@ -58,9 +116,37 @@ const char *fn; substdio ss; int fd; int match; +#ifdef USE_CONTROLDB + int rc; + + logit(128, "control_readline: Looking for: '%s'\n", fn); + /* Only try to get a value OTHER than these from the LDAP database: + * me, ldapserver, ldaplogin, ldappassword, ldapcontroldn and .cdb files. */ + if(verify_ldap_file_check(fn)) { + /* Connect to LDAP and find what we are looking for. */ + logit(128, " Searching LDAP\n"); + if( (rc = control_ldap_search(fn, sa, 0, 0)) > 0 ) { + /* Found what we where looking for. */ + logit(128, " 1:value (%s) = '%S'\n", fn, sa); + return 1; + } +#ifndef QLDAP_BAILOUT + else + /* Didn't find anything... */ + return 0; +#endif + } + /* We didn't find anything and QLDAP_BAILOUT is defined so we pass + * through here and search for the values in the real FS. */ + logit(128, " Searching FS\n"); +#endif /* end -- LDAP server query routines */ fd = open_read(fn); - if (fd == -1) { if (errno == error_noent) return 0; return -1; } + if (fd == -1) { +#ifdef USE_CONTROLDB + logit(128, " Can't open %s (errno=%d)\n", fn, errno); +#endif + if (errno == error_noent) return 0; return -1; } substdio_fdbuf(&ss,subread,fd,inbuf,sizeof(inbuf)); @@ -68,6 +154,12 @@ const char *fn; striptrailingwhitespace(sa); close(fd); +#ifdef USE_CONTROLDB + if(strstr(fn, "ldappassword")) + logit(128, " 2a:value (%s) = ''\n", fn); + else + logit(128, " 2b:value (%s) = '%S'\n", fn, sa); +#endif return 1; } @@ -76,6 +168,14 @@ int *i; const char *fn; { unsigned long u; +#ifdef USE_CONTROLDB + /* TURBO: Should this really be done!? + * 'line' is a global variable, and it have some + * 'weird' (?) values sometimes which isn't good + * for me/ldap... */ + if (!stralloc_copys(&line,"")) return -1; + if (!stralloc_0(&line)) return -1; +#endif switch(control_readline(&line,fn)) { case 0: return 0; @@ -102,6 +202,10 @@ const char *fn; case -1: return -1; } if (!stralloc_0(&line)) return -1; +#ifdef USE_CONTROLDB + if (0 == strcmp(line.s,"TRUE")) { *ul = 1; return 1; } + if (0 == strcmp(line.s,"FALSE")) { *ul = 0; return 1; } +#endif if (!scan_ulong(line.s,&u)) return 0; *ul = u; return 1; @@ -115,18 +219,64 @@ int flagme; substdio ss; int fd; int match; +#ifdef USE_CONTROLDB + int rc; + + logit(128, "control_readfile: Looking for: '%s'\n", fn); + /* Only try to get a value OTHER than these from the LDAP database: + * me, ldapserver, ldaplogin, ldappassword, ldapcontroldn and .cdb files. */ + if(verify_ldap_file_check(fn)) { + /* no idea why, but fn gets clobbered somewhere below here */ + const char *fn2 = strdup(fn); + /* Connect to LDAP and find what we are looking for. */ + logit(128, " Searching LDAP\n"); + if( (rc = control_ldap_search(fn2, sa, flagme, 1)) > 0) { + /* Found what we where looking for. */ + logit(128, " 3:value (%s) = '%S'\n", fn2, sa); + return 1; + } +#ifndef QLDAP_BAILOUT + else { + /* Didn't find anything... */ + if (flagme && meok) { + /* ... bug we require this value and it's ok to return 'me'. */ + if (!stralloc_copy(sa, &me)) return -1; + if (!stralloc_0(sa)) return -1; +#ifdef USE_CONTROLDB + logit(128, " 4a:value (%s) = '%S' (errno=%d)\n", fn2, sa, errno); +#endif + return 1; + } + + /* Return 'not found'. */ + return 0; + } +#endif + free(fn2); + } + + /* We didn't find anything, and if QLDAP_BAILOUT is defined so + * we pass through here and search for the values in the real FS. */ + logit(128, " Searching FS\n"); +#endif /* end -- LDAP server query routines */ if (!stralloc_copys(sa,"")) return -1; fd = open_read(fn); if (fd == -1) { +#ifdef USE_CONTROLDB + logit(128, " Can't open %s (errno=%d)\n", fn, errno); +#endif if (errno == error_noent) { if (flagme && meok) { if (!stralloc_copy(sa,&me)) return -1; if (!stralloc_0(sa)) return -1; +#ifdef USE_CONTROLDB + logit(128, " 4b:value (%s) = '%S' (errno=%d)\n", fn, sa, errno); +#endif return 1; } return 0; @@ -145,7 +295,13 @@ int flagme; if (line.s[0]) if (line.s[0] != '#') if (!stralloc_cat(sa,&line)) break; - if (!match) { close(fd); return 1; } + if (!match) { + close(fd); +#ifdef USE_CONTROLDB + logit(128, " 5:value (%s) = '%S'\n", fn, sa); +#endif + return 1; + } } close(fd); return -1; @@ -180,3 +336,374 @@ const char *fn; close(fd); return -1; } + +#ifdef USE_CONTROLDB +int control_ldap_search(fn, sa, flagme, multvalues) +const char *fn; +stralloc *sa; +int flagme; +int multvalues; +{ + int rc, entries = 0, i, ret_val = 0; + char **vals = NULL; + const char *attrs[] = { 0 }; + stralloc filter = {0}; + stralloc dn = {0}; + stralloc ldap_line = {0}; + char *basedn_orig; + int port, restore_basedn = 0; + + /* Do we have a location to search for the information in the first place!?! */ + if(! ldap_controldn.len) return -1; + + /* Remove the 'control/' part from the file name. */ + if(! str_diffn("control/", fn, 8) ) + attrs[0] = strchr(fn, '/') + 1; + else + /* Remove the '/var/qmail/control/' part from the file name. */ + if(! str_diffn("/var/qmail/control/", fn, 19) ) + attrs[0] = strrchr(fn, '/') + 1; + else + attrs[0] = fn; + attrs[1] = 0; + + /* Make sure we have a NULL terminated string with our hostname (me) */ + if(!ldap_me.len) { + /* The LDAP version of 'me' isn't set */ + if(me.len) { + /* We do have the 'ordinary me', use that... */ + if(! stralloc_copyb(&ldap_me, me.s, me.len)) _exit(QLX_NOMEM); + if(! stralloc_0(&ldap_me)) _exit(QLX_NOMEM); + } else { + /* The hostname ('me') isn't known AT ALL... Get it. */ + if (control_rldef(&ldap_me, "/var/qmail/control/me", 0, "") == -1) _exit(-1); + if (!stralloc_0(&ldap_me)) _exit(QLX_NOMEM); + logit(64, "init_ldap: control/me: %s\n", ldap_me.s); + } + } + logit(128, " me: %s\n", ldap_me.s); + + /* Build the search string for what we want. */ + if(! stralloc_copys(&filter, "(&(cn=") ) _exit(QLX_NOMEM); + if(! stralloc_cats(&filter, ldap_me.s) ) _exit(QLX_NOMEM); + if(! stralloc_cats(&filter, ")(objectclass=qmailControl))") ) _exit(QLX_NOMEM); + if(! stralloc_0(&filter)) _exit(QLX_NOMEM); + logit(256, " Search filter: %s\n", filter.s); + logit(256, " Below DN: %s\n", ldap_controldn.s); + logit(128, " Attribute(s): %s\n", flatten_attrib_array(attrs)); + + if(!q->ld) { + logit(1, "control_ldap_search: LDAP connection not initialized!\n"); +#ifdef QLDAP_BAILOUT + /* Don't FAIL if we can't search the LDAP server. Return 'not found' */ + logit(256, " return(0)\n"); + return(0); +#else + /* We REQUIRE LDAP, die. HARD! */ + logit(256, " _exit1(1)\n"); + _exit(1); +#endif + } + + if(ldap_basedn.len) { + /* Save the BaseDN so it can be restored later. */ + basedn_orig = alloc(ldap_basedn.len); + basedn_orig = strndup((const char *)ldap_basedn.s, ldap_basedn.len); + restore_basedn = 1; + } + + /* To make sure we search below the correct DN, put the ControlDN in the BaseDN variable */ + if(! stralloc_copys(&ldap_basedn, ldap_controldn.s) ) _exit(QLX_NOMEM); + if(! stralloc_0(&ldap_basedn)) _exit(QLX_NOMEM); + + /* Search for the desired information in the database. Search below ControlDN. */ + rc = qldap_lookup(q, filter.s, attrs); + if(rc != OK) { + if( !stralloc_copys(&filter, "")) _exit(QLX_NOMEM); + ret_val = -1; goto CLEANUP; + } + logit(256, " search for %s succeeded in control_ldap_search()\n", filter.s); + if(! stralloc_copys(&filter, "")) _exit(QLX_NOMEM); + + /* Count the results, we must have exactly one dn! */ + if( (entries = ldap_count_entries(q->ld, q->res)) != 1) { + /* Could not find the DN requested. Try a catchall DN. */ + + /* Build the CatchALL DN to connect to. */ + if(! stralloc_0(&ldap_controldn)) _exit(QLX_NOMEM); + if(! stralloc_copys(&dn, "cn=") ) _exit(QLX_NOMEM); + if(! stralloc_cats(&dn, CONTROL_CATCH_ALL)) _exit(QLX_NOMEM); + if(! stralloc_cats(&dn, ",")) _exit(QLX_NOMEM); + if(! stralloc_cats(&dn, ldap_controldn.s) ) _exit(QLX_NOMEM); + if(! stralloc_0(&dn)) _exit(QLX_NOMEM); + + /* Build the search string for what we want, from the catchall dn. */ + if(! stralloc_copys(&filter, "(&(cn=")) _exit(QLX_NOMEM); + if(! stralloc_cats(&filter, CONTROL_CATCH_ALL)) _exit(QLX_NOMEM); + if(! stralloc_cats(&filter, ")(objectclass=qmailControl))") ) _exit(QLX_NOMEM); + if(! stralloc_0(&filter)) _exit(QLX_NOMEM); + logit(256, " CATCHALL Search filter: %s\n", filter.s); + logit(256, " CATCHALL Below DN: %S\n", dn); + + /* Do the search for the desired attribute. */ + rc = qldap_lookup(q, filter.s, attrs); + if(rc != OK) { + if( !stralloc_copys(&filter, "")) _exit(QLX_NOMEM); + ret_val = -1; goto CLEANUP; + } + logit(256, " search for %s succeeded in control_ldap_search() (CATCHALL)\n", filter.s); + if(! stralloc_copys(&filter, "")) _exit(QLX_NOMEM); + + /* Count the results again, we must have exactly one */ + if( (entries = ldap_count_entries(q->ld, q->res)) != 1) + { ret_val = -1; goto CLEANUP; } + } + logit(256, " Found %d entries\n", entries); + + /* ------------------- */ + + /* Get the desired value. */ + if( ((vals = ldap_get_values(q->ld, q->msg, attrs[0])) == NULL) ) { + if( flagme ) ret_val = 1; + goto CLEANUP; + } + + /* Store the value retained, vals[*]. */ + if(! stralloc_copys(sa, "")) { ret_val = -1; goto CLEANUP; } + if (multvalues) { + /* Collect mult values here, do just like old control_readfile*/ + for( i = 0; vals[i] != NULL; i++ ) { + /* Append */ + if(! stralloc_copys(&ldap_line, vals[i])) _exit(QLX_NOMEM); + striptrailingwhitespace(&ldap_line); + if(!stralloc_0(&ldap_line)) _exit(QLX_NOMEM); + + if(!stralloc_cat(sa,&ldap_line)) _exit(QLX_NOMEM); + if(vals[i+1] == NULL) break; + } + } else { + if(vals[0] != NULL) { + if(ldap_count_values(vals) != 1) + logit(4, "control_ldap_search: too many values for '%s', we choose first one!", flatten_attrib_array(attrs)); + + /* Append */ + if(! stralloc_copys(sa, vals[0])) _exit(QLX_NOMEM); + striptrailingwhitespace(sa); + } + } + + if(sa->len) + ret_val = 1; + else + if(meok) { + logit(128, " control_ldap_search: meok=%d, me=%S, ldap_me=%S\n", meok, me, ldap_me); + if(!stralloc_copy(sa,&me)) ret_val = -1; + if(!stralloc_0(sa)) ret_val = -1; + } + /* ------------------- */ + + CLEANUP: + /* Free the value retrived. */ + /* alloc_free(attrs); + * if(vals) + * ldap_value_free(vals); */ + + if(restore_basedn) { + /* Restore the BaseDN value */ + if(! stralloc_copys(&ldap_basedn, basedn_orig) ) _exit(QLX_NOMEM); + if(! stralloc_0(&ldap_basedn)) _exit(QLX_NOMEM); + alloc_free(basedn_orig); + } + + return ret_val; +} +#endif /* end -- LDAP server query routines */ + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +void qldap_getcontrols_securebind(char *securebind) +{ + int argc, i; + char **arguments; + +#ifdef USE_CONTROLDB + /* Should we use SSL (ldaps) to the LDAP server? + * -> Only do this if '-Z' is _NOT_ given, + * ie, we're not using TLS! + */ + if(ldap_server.len > 0) { + if(!strncasecmp(ldap_server.s, "ldaps://", 8)) + use_ssl = 1; + else if(!strncasecmp(ldap_server.s, "ldapi://", 8) || + !strncasecmp(ldap_server.s, "ldap://", 7)) + use_uri = 1; + } +#endif + + logit(128, "qldap_getcontrols_securebind: retreiving secure bind options: use_uri=%d, use_ssl=%d\n", + use_uri, use_ssl); + + /* Convert the string from the ldapsecurebind file to an argv which we + * must cyckle through to find all of our arguments. */ + arguments = alloc(strlen(securebind)+1); + argc = string2argv(arguments, securebind); + if(! argc) return; + + /* Now parse this secure bind information */ + for(i = 0; i < argc; i++) { +#if 0 + logit(256, " arguments[%d]=%s\n",i,arguments[i]); +#endif + switch(arguments[i][1]) { +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_ALL) + case 'O': + /* SASL security properties */ + i++; + sasl_secprops = strdup(arguments[i]); + logit(128, " SASL Secprops: %s\n", sasl_secprops); + break; + case 'Q': + /* SASL Quiet mode */ + sasl_flags = LDAP_SASL_QUIET; + logit(128, " Use SASL quiet mode: TRUE\n"); + break; + case 'R': + /* SASL realm */ + i++; + sasl_realm = strdup(arguments[i]); + logit(128, " SASL Realm: %s\n", sasl_realm); + break; + case 'U': + /* Username for SASL bind. The syntax of the username depends + * on the actual SASL mechanism used. + */ + i++; + sasl_authc_id = strdup(arguments[i]); + logit(128, " SASL Authc ID: %s\n", sasl_authc_id); + break; + case 'X': + /* Requested authorization ID for SASL bind. Authzid must be + * one of the following formats: + * dn: + * or + * u: + */ + i++; + sasl_authz_id = strdup(arguments[i]); + logit(128, " SASL Authz ID: %s\n", sasl_authz_id); + break; + case 'Y': + /* the SASL mechanism to be used for authentication. If it's + * not specified, the program will choose the best mechanism + * the server knows. + */ + i++; + sasl_mech = strdup(arguments[i]); + logit(128, " SASL MECH: %s\n", sasl_mech); + break; +#endif +#if defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + case 'Z': + /* Issue StartTLS (Transport Layer Security) extended operation. */ + if(!use_ssl) { + use_tls++; + logit(128, " Bind with TLS: TRUE\n"); + } else + logit(2, "qldap_getcontrols_securebind: Can't combine both SSL and TLS (ldaps:// specified in 'ldapserver')\n"); + break; +#endif + default: + logit(8, "qldap_getcontrols_securebind: Unknown Secure BIND option: %s ", arguments[i]); + if(arguments[i+1]) { + i++; + logit(8, "(%s)\n", arguments[i]); + } + break; + } + } + logit(128, " done.\n"); + alloc_free(arguments); +} + +// Split a char* to a argument string (char**) based on spaces +int string2argv(char **out, char *in) { + char *args, **buffer, *temp; + int argc = 0, i; + + if(strlen(in)) { + buffer = alloc(strlen(in)+1); + temp = alloc(strlen(in)+1); + + temp = strdup(in); + args = strtok_r(temp, " ", buffer); + + do { + args += '\0'; + out[argc] = strdup(args); + logit(128, " string2argv: out[%d] = %s\n", argc, out[argc]); + + argc++; + } while(args = strtok_r(NULL, " ", buffer)); + alloc_free(buffer); alloc_free(temp); + + logit(128, " string2argv: arguments = %d\n", argc); + } + + return(argc); +} +#endif + +#ifdef USE_CONTROLDB +/* This function will return TRUE if file is OK to fetch from LDAP */ +int verify_ldap_file_check(const char *fn) { + if(!strstr(fn, ".cdb") +#if 0 + /* THIS IS WHAT I WOULD _LIKE_ TO DO */ + + /* BUG: Looking for 'ldapmessagestore', 'ldaptimeout' + * etc will match here because of the 'me' check (both + * contain the characters 'me')! */ + && !strstr(fn, "me") + && !strstr(fn, "ldapserver") + && !strstr(fn, "ldapcontroldn") + && !strstr(fn, "ldaplogin") + && !strstr(fn, "ldappassword") +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + && !strstr(fn, "ldapsecurebind") +#endif +#else + /* BECAUSE OF BUG ABOVE, I HAD TO RESORT TO THIS */ + + && strncmp(fn, "me", 2) && strcmp(fn, "control/me") && strcmp(fn, "/var/qmail/control/me") + && strcmp(fn, "ldapserver") && strcmp(fn, "control/ldapserver") && strcmp(fn, "/var/qmail/control/ldapserver") + && strcmp(fn, "ldapcontroldn") && strcmp(fn, "control/ldapcontroldn") && strcmp(fn, "/var/qmail/control/ldapcontroldn") + && strcmp(fn, "ldaplogin") && strcmp(fn, "control/ldaplogin") && strcmp(fn, "/var/qmail/control/ldaplogin") + && strcmp(fn, "ldappassword") && strcmp(fn, "control/ldappassword") && strcmp(fn, "/var/qmail/control/ldappassword") +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + && strcmp(fn, "ldapsecurebind") && strcmp(fn, "control/ldapsecurebind") && strcmp(fn, "/var/qmail/control/ldapsecurebind") +#endif +#endif + /* Do we have what we need for an LDAP search!? */ + && ldap_controldn.len + && (me.len || ldap_me.len) + && q->ld) + return 1; + return 0; +} + +char *flatten_attrib_array(const char *attrs[]) { + int i; + stralloc string = {0}; + + for(i=0; attrs[i]; i++) { + logit(256, " attrs[%d]: '%s'\n", i, attrs[i]); + if(! stralloc_copys(&string, attrs[i]) ) _exit(QLX_NOMEM); + + if(attrs[i+1]) + if(! stralloc_cats(&string, ", ") ) _exit(QLX_NOMEM); + } + if(! stralloc_0(&string)) _exit(QLX_NOMEM); + + logit(256, " string: '%s'\n", string.s); + return(string.s); +} +#endif Index: qmail-1.03/control.h =================================================================== --- qmail-1.03.orig/control.h +++ qmail-1.03/control.h @@ -11,4 +11,30 @@ extern int control_readulong(unsigned lo extern int control_readfile(stralloc *, const char *, int); extern int control_readrawfile(stralloc *, const char *); +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#include "constmap.h" +#include "stralloc.h" + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_ALL) +extern unsigned sasl_flags; +extern char *sasl_secprops; +extern char *sasl_realm; +extern char *sasl_authc_id; +extern char *sasl_authz_id; +extern char *sasl_mech; + +typedef struct lutil_sasl_defaults_s { + char *mech; + char *realm; + char *authcid; + char *passwd; + char *authzid; +} lutilSASLdefaults; +#endif + +extern int use_tls; +extern int use_ssl; +extern stralloc qldap_securebind; +struct constmap mapbinds; +#endif #endif Index: qmail-1.03/pbsadd.c =================================================================== --- qmail-1.03.orig/pbsadd.c +++ qmail-1.03/pbsadd.c @@ -49,6 +49,28 @@ #include "str.h" #include "stralloc.h" #include "substdio.h" +#include "qldap.h" + +#ifdef USE_CONTROLDB +qldap *q; + +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif static void die(void); static void logit(const char* ); @@ -99,6 +121,10 @@ setup(void) if (chdir(auto_qmail) == -1) die_control(); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die_dir(); +#endif + if (control_readfile(&addresses,"control/pbsservers",0) != 1) die_control(); @@ -113,6 +139,10 @@ setup(void) if (control_readfile(&envs,"control/pbsenv",0) == -1) die_control(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif + if (fchdir(fdsourcedir) == -1) die_dirback(); close(fdsourcedir); @@ -271,6 +301,9 @@ done: static void die(void) { +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(1); } @@ -342,7 +375,11 @@ static void log_nomem(void) { logit("pbsadd out of memory"); +#ifdef USE_CONTROLDB + if (*childargs) { qldap_close(q); _exit(111); } +#else if (*childargs) _exit(111); +#endif else execvp(*childargs,childargs); /* should never reach this point */ die_exec(); Index: qmail-1.03/pbscheck.c =================================================================== --- qmail-1.03.orig/pbscheck.c +++ qmail-1.03/pbscheck.c @@ -51,6 +51,28 @@ #include "substdio.h" #include "timeoutread.h" #include "timeoutwrite.h" +#include "qldap.h" + +#ifdef USE_CONTROLDB +qldap *q; + +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif static void die(void); static int safewrite(int, void *, int); @@ -102,6 +124,9 @@ setup(void) die_dir(); if (chdir(auto_qmail) == -1) die_control(); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die_dir(); +#endif if (control_readfile(&addresses,"control/pbsservers",0) != 1) die_control(); @@ -113,6 +138,9 @@ setup(void) if (control_readfile(&envs,"control/pbsenv",0) == -1) die_control(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif if (fchdir(fdsourcedir) == -1) die_dirback(); close(fdsourcedir); Index: qmail-1.03/pbsdbd.c =================================================================== --- qmail-1.03.orig/pbsdbd.c +++ qmail-1.03/pbsdbd.c @@ -46,6 +46,28 @@ #include "strerr.h" #include "substdio.h" #include "uint32.h" +#include "qldap.h" + +#ifdef USE_CONTROLDB +qldap *q; + +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif static void die_control(void); static void die_nomem(void); @@ -101,6 +123,9 @@ init(void) unsigned int l; if (chdir(auto_qmail) == -1) die_control(); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die_control(); +#endif if (control_rldef(&addr,"control/pbsip",0, "0.0.0.0") == -1) die_control(); @@ -121,6 +146,10 @@ init(void) if (control_readint(&timeout,"control/pbstimeout") == -1) die_control(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif + cache = alloc(cachesize); if (!cache) die_nomem(); Index: qmail-1.03/qldap-cluster.c =================================================================== --- qmail-1.03.orig/qldap-cluster.c +++ qmail-1.03/qldap-cluster.c @@ -53,6 +53,7 @@ cluster_init(void) if (control_readline(&me, "control/me") != 1) return -1; + if (control_readint(&clusteron, "control/ldapcluster") == -1) return -1; logit(64, "init: control/ldapcluster: %i\n", clusteron); Index: qmail-1.03/qldap-errno.h =================================================================== --- qmail-1.03.orig/qldap-errno.h +++ qmail-1.03/qldap-errno.h @@ -74,6 +74,13 @@ extern int qldap_errno; #define LDAP_BIND_UNREACH 31 /* ldap server down or unreachable */ #define LDAP_BIND_AUTH 32 /* wrong bind password */ +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#define LDAP_INIT_SSL 91 /* error while initializing ldaps connection */ +#define LDAP_INIT_TLS 92 /* error while initializing ldap/TLS connection */ +#define LDAP_INIT_SASL 93 /* error while initializing SASL bind */ +#define LDAP_INIT_OPT_SASL 94 /* error while setting SASL options */ +#endif + const char *qldap_err_str(int enbr); /* returns a string that corresponds to the qldap_errno */ Index: qmail-1.03/qldap.c =================================================================== --- qmail-1.03.orig/qldap.c +++ qmail-1.03/qldap.c @@ -52,6 +52,45 @@ #include "qldap.h" +#ifdef USE_CONTROLDB +qldap *q; + +stralloc ldap_me = {0}; +stralloc ldap_controldn = {0}; +stralloc ldap_port = {0}; +#endif +stralloc ldap_server = {0}; +stralloc ldap_basedn = {0}; +stralloc objectclass = {0}; +stralloc ldap_login = {0}; +stralloc ldap_password = {0}; +stralloc default_messagestore = {0}; +stralloc dotmode = {0}; +unsigned int ldap_timeout = QLDAP_TIMEOUT; /* default timeout is 30 secs */ +int rebind = 0; /* default off */ +int default_uid = 0; +int default_gid = 0; +unsigned long quotasize = 0; +unsigned long quotacount = 0; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#include + +int use_tls = 0; +int use_ssl = 0; +int use_uri = 0; + +unsigned sasl_flags = LDAP_SASL_AUTOMATIC; +char *sasl_secprops = NULL; +char *sasl_realm = NULL; +char *sasl_authc_id = NULL; +char *sasl_authz_id = NULL; +char *sasl_mech = NULL; + +stralloc ldap_securebind = {0}; +#endif + +#if !defined(USE_CONTROLDB) && !defined(SECUREBIND_SASL) && !defined(SECUREBIND_SSL) && !defined(SECUREBIND_TLS) && !defined(SECUREBIND_ALL) struct qldap { int state; #define NEW 0 @@ -68,22 +107,8 @@ struct qldap { /* should we store server, binddn, basedn, password, ... */ }; -stralloc ldap_server = {0}; -stralloc basedn = {0}; -stralloc objectclass = {0}; -stralloc ldap_login = {0}; -stralloc ldap_password = {0}; -stralloc default_messagestore = {0}; -stralloc dotmode = {0}; -unsigned int ldap_timeout = QLDAP_TIMEOUT; /* default timeout is 30 secs */ -int rebind = 0; /* default off */ -unsigned int default_uid = 0; -unsigned int default_gid = 0; -unsigned long quotasize = 0; -unsigned long quotacount = 0; - - static int qldap_close(qldap *); +#endif static int qldap_set_option(qldap *, int); static int check_next_state(qldap *, int); @@ -99,7 +124,6 @@ static int check_next_state(qldap *, int } \ } while (0) - int qldap_ctrl_login(void) { @@ -143,6 +167,9 @@ qldap_ctrl_trylogin(void) int qldap_ctrl_generic(void) { +#ifdef USE_CONTROLDB + char *pos; +#endif /* set defaults, so that a reread works */ ldap_timeout = QLDAP_TIMEOUT; /* default timeout is 30 secs */ rebind = 0; /* default off */ @@ -157,35 +184,74 @@ qldap_ctrl_generic(void) byte_repl(ldap_server.s, ldap_server.len - 1, '\0', ' '); else if (!stralloc_0(&ldap_server)) return -1; - logit(64, "init_ldap: control/ldapserver: '%s'\n", ldap_server.s); + logit(64, "init_ldap: control/ldapserver: '%s'\n\n", ldap_server.s); + +#ifdef USE_CONTROLDB + pos = strchr(ldap_server.s, ':'); + if(pos && + !strstr(ldap_server.s, "ldap://") && + !strstr(ldap_server.s, "ldaps://") && + !strstr(ldap_server.s, "ldapi://")) + { + /* strchr() will return everything (including) the first ':' character */ + pos++; /* We're not 'interested' in the : character! */ + + /* Put it in 'ldap_port' where it belongs. */ + stralloc_copys(&ldap_port, pos); + stralloc_0(&ldap_port); + + logit(64, "init_ldap: port retreived from control/ldapserver: %s\n\n", ldap_port.s); + } else { + /* Not defined in 'control/ldapserver', try the 'control/port_ldap' file. */ + if (control_rldef(&ldap_port, "control/port_ldap", 0, "389") == -1) + return -1; + if (!stralloc_0(&ldap_port)) return -1; + logit(64, "init_ldap: control/port_ldap: %s\n\n", ldap_port.s); + } + + if (control_rldef(&ldap_controldn, "control/ldapcontroldn", 0, "") == -1) + return -1; + if (!stralloc_0(&ldap_controldn)) return -1; + logit(64, "init_ldap: control/ldapcontroldn: %s\n\n", ldap_controldn.s); + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + if (control_rldef(&ldap_securebind,"control/ldapsecurebind",0,"nosecure") != -1) { + if (!stralloc_0(&ldap_securebind)) return -1; + qldap_getcontrols_securebind(ldap_securebind.s); + } +#endif + + /* Connect and bind to LDAP server */ + qldap_ctrl_bind(); +#endif - if (control_rldef(&basedn, "control/ldapbasedn", 0, "") == -1) + if (control_rldef(&ldap_basedn, "control/ldapbasedn", 0, "") == -1) return -1; - if (!stralloc_0(&basedn)) return -1; - logit(64, "init_ldap: control/ldapbasedn: %s\n", basedn.s); + if (!stralloc_0(&ldap_basedn)) return -1; + logit(64, "init_ldap: control/ldapbasedn: %s\n\n", ldap_basedn.s); if (control_rldef(&objectclass, "control/ldapobjectclass", 0, "") == -1) return -1; - logit(64, "init_ldap: control/ldapobjectclass: %S\n", &objectclass); + logit(64, "init_ldap: control/ldapobjectclass: %S\n\n", &objectclass); if (control_readint(&ldap_timeout, "control/ldaptimeout") == -1) return -1; - logit(64, "init_ldap: control/ldaptimeout: %i\n", ldap_timeout); + logit(64, "init_ldap: control/ldaptimeout: %i\n\n", ldap_timeout); if (control_readint(&rebind, "control/ldaprebind") == -1) return -1; - logit(64, "init_ldap: control/ldaprebind: %i\n", rebind); + logit(64, "init_ldap: control/ldaprebind: %i\n\n", rebind); /* defaults */ if (control_readint(&default_uid, "control/ldapuid") == -1) return -1; if (default_uid != 0) - logit(64, "init_ldap: control/ldapuid: %i\n", default_uid); + logit(64, "init_ldap: control/ldapuid: %i\n\n", default_uid); if (control_readint(&default_gid, "control/ldapgid") == -1) return -1; if (default_gid != 0) - logit(64, "init_ldap: control/ldapgid: %i\n", default_gid); + logit(64, "init_ldap: control/ldapgid: %i\n\n", default_gid); if (control_rldef(&default_messagestore, "control/ldapmessagestore", 0, "") == -1) @@ -194,7 +260,7 @@ qldap_ctrl_generic(void) if (default_messagestore.s[default_messagestore.len-1] != '/') if (!stralloc_append(&default_messagestore, "/")) return -1; - logit(64, "init_ldap: control/ldapmessagestore: %S\n", + logit(64, "init_ldap: control/ldapmessagestore: %S\n\n", &default_messagestore); } else if (!stralloc_copys(&default_messagestore, "")) return -1; @@ -202,14 +268,14 @@ qldap_ctrl_generic(void) if (control_rldef(&dotmode, "control/ldapdefaultdotmode", 0, "ldaponly") == -1) return -1; if (!stralloc_0(&dotmode)) return -1; - logit(64, "init_ldap: control/ldapdefaultdotmode: %s\n", dotmode.s); + logit(64, "init_ldap: control/ldapdefaultdotmode: %s\n\n", dotmode.s); if (control_readulong("asize, "control/defaultquotasize") == -1) return -1; if (control_readulong("acount, "control/defaultquotacount") == -1) return -1; - logit(64, "init_ldap: control/defaultquotasize: %u\n", quotasize); - logit(64, "init_ldap: control/defaultquotacount: %u\n", quotacount); + logit(64, "init_ldap: control/defaultquotasize: %u\n\n", quotasize); + logit(64, "init_ldap: control/defaultquotacount: %u\n\n", quotacount); return 0; } @@ -223,13 +289,15 @@ qldap_need_rebind(void) char * qldap_basedn(void) { - return basedn.s; + return ldap_basedn.s; } qldap * qldap_new(void) { +#ifndef USE_CONTROLDB qldap *q; +#endif q = (qldap *)alloc(sizeof(qldap)); if (q == 0) return (qldap *)0; @@ -243,15 +311,73 @@ int qldap_open(qldap *q) { int rc; +#ifdef USE_CONTROLDB + int port, version; +#endif CHECK(q, OPEN); /* allocate the connection */ +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + logit(128, " qldap_open: use_uri=%d, use_ssl=%d, use_tls=%d\n", use_uri, use_ssl, use_tls); + if(use_uri || use_ssl) { + /* Connect to LDAP server using either LDAP URI (ldapi) or SSL (ldaps). */ + logit(128, " qldap_open: ldap_initialize(ld, %s) -> ", ldap_server.s); + + rc = ldap_initialize(&q->ld, ldap_server.s); + if(rc != LDAP_SUCCESS) { + logit(1, "qldap_open: ldap_initialize failed (%s)\n", ldap_err2string(rc)); + logit(128, "FAILED\n"); + return ERRNO; + } + logit(128, "SUCCESS\n"); + } else { + /* Do not use LDAP URI (ldapi) or SSL (ldaps) to connect to LDAP server. */ + port = atoi(ldap_port.s); + logit(128, " qldap_open: ldap_init(%s, %d) -> ", ldap_server.s, port); + if ((q->ld = ldap_init(ldap_server.s, port)) == 0) { +#else + logit(128, " qldap_open: ldap_init(%s, %d): ", ldap_server.s, LDAP_PORT); if ((q->ld = ldap_init(ldap_server.s,LDAP_PORT)) == 0) { - logit(128, "qldap_open: init failed\n"); +#endif + logit(128, "FAILED\n"); return ERRNO; } - logit(128, "qldap_open: init successful\n"); + logit(128, "SUCCESS\n"); + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + } + + /* Directly stolen from the ldapsearch.c file in OpenLDAP (v2.0.27) */ + if(use_tls) { + logit(128, "qldap_open: Trying to start TLS (%d)\n", use_tls); + + /* Make sure we use LDAPv3 when trying TLS (a requirenment) */ + version = LDAP_VERSION3; + logit(128, " Setting LDAP protocol version to %d: ", version); + if(ldap_set_option(q->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS ) { + logit(128, "FAILED\n"); + + logit(1, "Setting LDAP version to LDAPv3 FAILED\n"); + return ERRNO; + } + logit(128, "SUCCESS\n"); + + /* Initialize the TLS connection */ + logit(128, " Starting TLS: "); + if(ldap_start_tls_s(q->ld, NULL, NULL) != LDAP_SUCCESS) { + if(use_tls > 1) { + logit(128, "failed (hard error)\n"); + + logit(1, "Starting TLS failed\n"); + return ERRNO; + } else { + ldap_perror(q->ld, "ldap_start_tls"); + } + } else + logit(128, "SUCCESS\n"); + } +#endif rc = qldap_set_option(q, 0); if (rc != OK) @@ -286,33 +412,33 @@ retry: */ switch (rc) { case LDAP_SUCCESS: - logit(128, "qldap_bind: successful\n"); + logit(128, " qldap_bind: successful\n\n"); q->state = BIND; return OK; case LDAP_TIMELIMIT_EXCEEDED: case LDAP_SERVER_DOWN: - logit(128, "qldap_bind: failed (%s)\n", ldap_err2string(rc)); + logit(128, " qldap_bind: failed (%s)\n\n", ldap_err2string(rc)); q->state = ERROR; return LDAP_BIND_UNREACH; case LDAP_INVALID_CREDENTIALS: - logit(128, "qldap_bind: failed (%s)\n", ldap_err2string(rc)); + logit(128, " qldap_bind: failed (%s)\n\n", ldap_err2string(rc)); q->state = ERROR; return LDAP_BIND_AUTH; case LDAP_PROTOCOL_ERROR: - logit(128, "qldap_bind: failed wrong protocol (%s)\n", + logit(128, " qldap_bind: failed wrong protocol (%s)\n\n", ldap_err2string(rc)); /* bind failed try Version 2 */ if (try > 1) break; - logit(128, "qldap_bind: retrying bind with Version 1\n"); + logit(128, " qldap_bind: retrying bind with Version 1\n\n"); qldap_close(q); rc = qldap_open(q); - logit(128, "qldap_bind: opened conection for Version 1\n"); + logit(128, " qldap_bind: opened conection for Version 1\n\n"); qldap_set_option(q, 1); - logit(128, "qldap_bind: set options for Version 1\n"); + logit(128, " qldap_bind: set options for Version 1\n\n"); if (rc != OK) break; goto retry; default: - logit(128, "qldap_bind: failed (%s)\n", ldap_err2string(rc)); + logit(128, " qldap_bind: failed (%s)\n\n", ldap_err2string(rc)); break; } q->state = ERROR; @@ -334,7 +460,11 @@ qldap_rebind(qldap *q, const char *bindd return qldap_bind(q, binddn, passwd); } +#ifdef USE_CONTROLDB +int +#else static int +#endif qldap_close(qldap *q) { CHECK(q, CLOSE); @@ -377,14 +507,17 @@ qldap_lookup(qldap *q, const char *filte struct timeval tv; int rc; unsigned int num_entries; - + CHECK(q, SEARCH); tv.tv_sec = ldap_timeout; tv.tv_usec = 0; - rc = ldap_search_st(q->ld, basedn.s, LDAP_SCOPE_SUBTREE, + logit(256, " qldap_lookup(): ldap_search_st(q->ld, '%s', '%d', '%s', '%s', ...)\n", + qldap_basedn(), LDAP_SCOPE_SUBTREE, filter, flatten_attrib_array(attrs)); + rc = ldap_search_st(q->ld, qldap_basedn(), LDAP_SCOPE_SUBTREE, filter, (char **)attrs, 0, &tv, &q->res); + logit(256, " ldap_search_st() return code=%d\n", rc); switch (rc) { /* probably more detailed information should be returned, eg.: @@ -399,8 +532,12 @@ qldap_lookup(qldap *q, const char *filte */ case LDAP_SUCCESS: - logit(128, "qldap_lookup: search for %s succeeded\n", - filter); +#ifdef USE_CONTROLDB + logit(128, " BaseDN: %s\n", qldap_basedn()); + logit(128, " search for %s succeeded in qldap_lookup()\n", filter); +#else + logit(128, "qldap_lookup: search for %s succeeded\n", filter); +#endif break; case LDAP_TIMEOUT: case LDAP_TIMELIMIT_EXCEEDED: @@ -838,7 +975,14 @@ qldap_get_attr(qldap *q, const char *att return FAILED; } #endif +#ifdef USE_CONTROLDB + /* If it don't exists, it's on purpose! It's LDAP for god sake!!! + * Dang, this message is irritating!! I don't give a rat's ass about it, + * but maybe SOMEONE do, so higher debuglevel to show it. */ + logit(256, "qldap_get_attr(%s): no such attribute\n", attr); +#else logit(128, "qldap_get_attr(%s): no such attribute\n", attr); +#endif return NOSUCH; } nvals = ldap_count_values(vals); @@ -992,12 +1136,10 @@ qldap_set_option(qldap *q, int forceV2) LDAP_OPT_ON); } if (rc != LDAP_OPT_SUCCESS) - logit(128, "qldap_set_option: " - "enabling referrals failed (%s)\n", + logit(128, " qldap_set_option: enabling referrals failed (%s)\n", ldap_err2string(rc)); else - logit(128, "qldap_set_option: " - "set referrals successful\n"); + logit(128, " qldap_set_option: set referrals successful\n"); /* referral errors are ignored */ #endif } @@ -1055,3 +1197,39 @@ check_next_state(qldap *q, int next) } } +#ifdef USE_CONTROLDB +int qldap_ctrl_bind(void) { + int rc; + + /* Allocate memory for the QmailLDAP session */ + logit(128, "qldap_ctrl_bind: Allocating memory for LDAP connection: "); + q = qldap_new(); + if(q == 0) { + logit(128, "FAILED\n"); + logit(1, "alert: unable to allocate memory for LDAP connection\n"); + return -1; + } + logit(128, "SUCCESS\n"); + + /* Open the connection to the LDAP server */ + logit(128, "qldap_ctrl_bind: Opening LDAP connection to %s:\n", ldap_server.s); + rc = qldap_open(q); + if(rc != OK) { + logit(128, " FAILED\n"); + logit(1, "alert: unable to open connection to LDAP server\n"); + return -1; + } + logit(128, " -> LDAP connection opened successfully\n"); + + /* Bind to the LDAP server */ + logit(128, "qldap_ctrl_bind: Binding to LDAP server as %s:\n", ldap_login.s); + rc = qldap_bind(q, ldap_login.s, ldap_password.s); + if(rc != OK) { + logit(128, " FAILED\n\n"); + logit(1, "alert: unable to bind to LDAP server\n"); + return -1; + } + + return 0; +} +#endif Index: qmail-1.03/qldap.h =================================================================== --- qmail-1.03.orig/qldap.h +++ qmail-1.03/qldap.h @@ -44,11 +44,34 @@ #define SCOPE_ONELEVEL 0x20 #define SCOPE_SUBTREE 0x30 +#ifdef USE_CONTROLDB +#include +struct qldap { + int state; +#define NEW 0 +#define OPEN 1 +#define BIND 2 +#define SEARCH 3 +#define EXTRACT 4 +#define REBIND 5 +#define CLOSE 6 +#define ERROR -1 + LDAP *ld; + LDAPMessage *res; /* valid after a search */ + LDAPMessage *msg; /* valid after call to ldap_first_entry() */ + /* should we store server, binddn, basedn, password, ... */ +}; +#endif + typedef struct qldap qldap; int qldap_ctrl_login(void); int qldap_ctrl_trylogin(void); int qldap_ctrl_generic(void); +#ifdef USE_CONTROLDB +int qldap_ctrl_ldap(void); +int qldap_ctrl_bind(void); +#endif int qldap_need_rebind(void); char *qldap_basedn(void); qldap *qldap_new(void); @@ -67,6 +90,9 @@ int qldap_rebind(qldap *, const char *, */ int qldap_free_results(qldap *); int qldap_free(qldap *); +#ifdef USE_CONTROLDB +int qldap_close(qldap *); +#endif /* possible errors: * FAILED TIMEOUT TOOMANY NOSUCH Index: qmail-1.03/qlx.h =================================================================== --- qmail-1.03.orig/qlx.h +++ qmail-1.03/qlx.h @@ -39,4 +39,10 @@ #define QLX_DIRMAKEHARD 168 #define QLX_DIRMAKECRASH 169 +#ifdef USE_CTRLD +/* QmailLDAP/Controls proxy errors */ +#define QLX_QLC_CONNFAIL 180 +#define QLX_QLC_BINDFAIL 181 +#endif + #endif Index: qmail-1.03/qmail-forward.c =================================================================== --- qmail-1.03.orig/qmail-forward.c +++ qmail-1.03/qmail-forward.c @@ -49,6 +49,21 @@ #define FATAL "qmail-forward: fatal: " +#ifdef USE_CONTROLDB +#include "qldap.h" +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif +#endif + void usage(void) { @@ -131,8 +146,10 @@ main (int argc, char **argv) if (chdir(auto_qmail) == -1) strerr_die4sys(111, FATAL, "Unable to switch to ", auto_qmail, ": "); + if (control_init() == -1) strerr_die2sys(111, FATAL, "Unable to read controls: "); + if (control_readline(&me, "control/me") != 1) strerr_die2sys(111, FATAL, "Unable to read control/me: "); Index: qmail-1.03/qmail-group.c =================================================================== --- qmail-1.03.orig/qmail-group.c +++ qmail-1.03/qmail-group.c @@ -63,6 +63,20 @@ #define FATAL "qmail-group: fatal: " +#ifdef USE_CONTROLDB +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif +#endif + void temp_nomem(void) { @@ -121,7 +135,7 @@ unsigned int nummoderators; int main(int argc, char **argv) { - qldap *qlc; + qldap *q; char *maildir; int flagm, flagc, flags, flagS; @@ -134,7 +148,7 @@ main(int argc, char **argv) bouncefx(); flagc = flags = flagS = flagm = 0; - qlc = ldapgroup(dname, &flagc, &flags, &flagS); + q = ldapgroup(dname, &flagc, &flags, &flagS); /* need to distinguish between new messages and responses */ if (action.s) { @@ -160,14 +174,14 @@ main(int argc, char **argv) "by that name. (#5.1.1)"); } else { if (flags) - subscribed(qlc, flagS); + subscribed(q, flagS); if (flagc || nummoderators) secretary(maildir, flagc); } reopen(); - explode(qlc); - qldap_free(qlc); + explode(q); + qldap_free(q); /* does not return */ blast(&recips, 1); Index: qmail-1.03/qmail-inject.c =================================================================== --- qmail-1.03.orig/qmail-inject.c +++ qmail-1.03/qmail-inject.c @@ -41,6 +41,31 @@ int mailusertokentype; char *mailrhost; const char *mailruser; +#include "qldap.h" + +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_me; +extern stralloc ldap_server; +extern stralloc ldap_controldn; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif + stralloc control_idhost = {0}; stralloc control_defaultdomain = {0}; stralloc control_defaulthost = {0}; @@ -58,8 +83,13 @@ void put(const char *s, unsigned int len { if (flagqueue) qmail_put(&qqt,s,len); else substdio_put(subfdout,s,len); } void putstr(const char *s) { put(s,str_len(s)); } +#ifdef USE_CONTROLDB +void perm() { qldap_close(q); _exit(100); } +void temp() { qldap_close(q); _exit(111); } +#else void perm() { _exit(100); } void temp() { _exit(111); } +#endif void die_nomem() { substdio_putsflush(subfderr,"qmail-inject: fatal: out of memory\n"); temp(); } void die_invalid(sa) stralloc *sa; { @@ -647,7 +677,11 @@ void getcontrols() mft_init(); if (chdir(auto_qmail) == -1) die_chdir(); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die_chdir(); +#else if (control_init() == -1) die_read(); +#endif if (control_rldef(&control_defaultdomain,"control/defaultdomain",1,"defaultdomain") != 1) die_read(); @@ -677,6 +711,9 @@ void getcontrols() die_read(); x = env_get("QMAILIDHOST"); if (x) if (!stralloc_copys(&control_idhost,x)) die_nomem(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif } #define RECIP_DEFAULT 1 Index: qmail-1.03/qmail-ldap-control/README =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/README @@ -0,0 +1,18 @@ +These are some files used either by me when testing QmailLDAP/Controls +or for setting it up... + +Also, if you have any problem with the QmailLDAP/Controls patch, please +visit http://bugs.bayour.com (project 'QmailLDAP/Controls'). + +Make sure the bug is really with the patch, and that what you're trying +to do works with only the QmailLDAP patch (i.e. _without_ QmailLDAP/Controls). + +qmailControl.schema Load this into your LDAP server +ldapcfg.sh Setup the QmailLDAP/Controls file +create_dirs.pl Creates {home,mail} directries - suid root +qmail-maildrop A wrapper for combining MailDrop and QMail +qmail-queue.rules A TCPServer rules file for use with SpamAssasin +rc.debian A init script used on Debian GNU/Linux +rc.turbo A init script used by Turbo (uses MultiLog) +test_smtp.sh Script to check receive times on SMTP +load_queue.pl Load the mail queue for testing SMTP etc. Index: qmail-1.03/qmail-ldap-control/create_dirs.pl =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/create_dirs.pl @@ -0,0 +1,114 @@ +#!/usr/bin/perl -w + +# This script is called with two arguments by +# QmailLDAP/Controls: Full path to home directory +# and mail directory + +$DEBUG = 0; +if($DEBUG) { + open(DBG, ">> /tmp/create_dirs.dbg"); + printf(DBG "$$: ARGS='%s %s'\n", $ARGV[0], $ARGV[1]); +} + +exit 1 if(!$ARGV[0] && !$ARGV[1]); + +$ENV{PATH} = "/var/qmail/bin"; +@MAILDIRS = ('tmp', 'new', 'cur', '.Trash', '.Trash/tmp', '.Trash/new', '.Trash/cur'); +umask(0022); + +sub untaintPath { + my ($path) = @_; + + # Encode any weird chars. + $path =~ s{[^\w\-\.\,/:=+\~]} {'%' . sprintf('%2x', ord($&))}xeg; + $path =~ s{(^|/)[^/]+/\.\.}{}g; # Collapse all 'dir/..'. + + &HNUserError ("No relative paths allowed: '$path'") + if $path =~ m,(^|/)\.\.,; # if any '..' remains + $path =~ m{.*}; # Final untaint of the rest. + $path = $&; + return $path; +} + +# Get effective user/group ID +$gid = (getpwuid($<))[3]; +$uid = (getpwuid($<))[2]; +if(!$gid && !$uid) { + # For some reason getpwuid() doesn't work correctly + # The $< contains the uid (gid?) number... Weird... + $gid = $uid = $<; +} +print DBG "$$: running as $uid:$gid\n" if($DEBUG); + +# Untaint the path to make suid perl happy +$HPATH = untaintPath($ARGV[0]); +$MPATH = untaintPath($ARGV[1]); + +@hpath = split('/', $HPATH); +@mpath = split('/', $MPATH); + +# ------------------------------------------------------------ + +# Create HOME directory recursivly +$directory = '/' . $hpath[1] . '/'; +for($i=1; $hpath[$i]; $i++) { + if(! -d $directory) { + if(! mkdir($directory, 0777) ) { + die("Unsuccessful in creating $directory, $!\n"); + } + print DBG "$$: mkdir($directory)\n" if($DEBUG); + } + + if($hpath[$i+1]) { + $directory .= $hpath[$i+1] . '/'; + } +} + +# Change owner/group on the last directory (to the user +# running the script). +chown($uid, $gid, $directory); +print DBG "$$: chown($uid, $gid, $directory)\n" if($DEBUG); + +if($MPATH ne './') { + # Create MAIL directory recursivly + $directory = '/' . $mpath[1] . '/'; + for($i=1; $mpath[$i]; $i++) { + if(! -d $directory) { + if(! mkdir($directory, 0777) ) { + die("Unsuccessful in creating $directory, $!\n"); + } + print DBG "$$: mkdir($directory)\n" if($DEBUG); + } + + if($mpath[$i+1]) { + $directory .= $mpath[$i+1] . '/'; + } + } + $MAIL_PATH=$MPATH; + + # Change owner/group on the last directory (to the user + # running the script). + chown($uid, $gid, $directory); + print DBG "$$: chown($uid, $gid, $directory)\n" if($DEBUG); +} else { + $MAIL_PATH=$HPATH; +} + +# Now, create the Maildir directories (tmp, new and cur). +foreach $dir (@MAILDIRS) { + $directory = $MAIL_PATH . $dir; + if(! -d $directory) { + if(! mkdir($directory, 0777) ) { + die("Unsuccessful in creating $directory, $!\n"); + } + print DBG "$$: mkdir($directory)\n" if($DEBUG); + + $gid = getgrnam("mail"); + chown($uid, $gid, $directory); + print DBG "$$: chown($uid, $gid, $directory)\n" if($DEBUG); + } +} + +print DBG "\n\n" if($DEBUG); +close(DBG) if($DEBUG); +exit(0); Index: qmail-1.03/qmail-ldap-control/ldapcfg.sh =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/ldapcfg.sh @@ -0,0 +1,330 @@ +#!/bin/bash + +# Configure the QMail LDAP files +# Author: Turbo Fredriksson +# Id: QmailLDAPConfig v0.1 Wed, 5 Jan 2000 04:37:47 +0100 + +# Files to change and there meaning... +# FILE: custombouncetext Additional custom text in bounce messages, e.g. for providing contact +# FILE: quotawarning Custom text in quota warning message, e.g. for providing contact information +# FILE: tarpitcount Tarpitcount is the number of RCPT TOs you accept before you start tarpitting +# FILE: tarpitdelay Tarpitdelay is the number of seconds of delay to introduce after each +# FILE: badrcptto This file lists recipient addresses that should be rejected. + +echo +echo +echo "Setting up QMail LDAP..." +echo "------------------------" + +# -------------------------------------------------------------------------------------------------- + +# FILE: ldapserver Space separated list of Hostnames or IP addresses of LDAP servers +set -- `/bin/ps ax | grep slapd | grep -v grep` +if [ "$1" != "" ]; then + echo + echo "I found that there is a SLAPD server running here. Do you want to use that for your" + echo -n "Qmail LDAP database (using 'localhost' as server) [Y/n] " + read s + if [ "$s" = "n" -o "$s" = "N" ]; then + echo -n "Oki, give me the FQDN (Fully Quallified Domain Name) of the LDAP server please: " + read LDAPSERVER + else + LDAPSERVER=localhost + fi +else + echo "I could not find a SLAPD server running on this computer, so you must give me the" + echo -n "FQDN (Fully Quallified Domain Name) of the LDAP server please: " + read LDAPSERVER +fi + +# FILE: ldapbasedn The base DN from where the search in the LDAP tree begins +if [ "$LDAPSERVER" = "localhost" -a -f /etc/openldap/slapd.conf ]; then + set -- `grep ^suffix /etc/openldap/slapd.conf` ; shift + LDAPBASEDN="`echo $* | sed 's/\"//g'`" + if [ "$LDAPBASEDN" != "" ]; then + echo + echo "I found that you Base DN is '$LDAPBASEDN'." + echo -n "Do you want to use that as the base of user searches? [Y/n] " + read s + if [ "$s" = "n" -o "$s" = "N" ]; then + echo -n "Oki, please give me the correct Base DN to start the searches from: " + read LDAPBASEDN + fi + fi +fi +if [ "$LDAPBASEDN" = "" ]; then + echo -n "Please give me the correct Base DN to start the searches from: " + read LDAPBASEDN +fi + +# FILE: ldapcontroldn +echo +echo -n "Do you want the QMail control information in the LDAP database? [Y/n] " +read s +if [ "$s" = "" ]; then + USE_LDAPCONTROLS=1 + echo + echo "Do you want me to create the database with all the nessecary values you have entered" + echo "here. If you choose to say yes here (default), I will create a LDIF file for you in" + echo "root's homedirectory which you will have to verify, and load with the program 'ldapadd'" + echo "with the right permissions. The file will be named '/root/qmail-ldap.ldif'..." + echo "You will also have to read the file '/usr/doc/qmail/QLDAPINSTALL.gz' for more information" + echo "about what schema you will have to have you LDAP server load and accept." + echo + echo -n "Do you want me to create a database file for you? [Y/n] " + read s + if [ "$s" = "" ]; then + CREATE_LDIF=1 + fi + + if [ "$LDAPSERVER" = "localhost" -a -f /etc/openldap/slapd.conf ]; then + set -- `grep ^suffix /etc/openldap/slapd.conf` ; shift + SUFFIX="`echo $* | sed 's/\"//g'`" + if [ "$SUFFIX" != "" ]; then + HOST="`hostname`" + DOMA="`dnsdomainname`" + FQDN="$HOST.$DOMA" + echo + echo "Do you want to use Base DN above for Qmail LDAP's control base (using '$SUFFIX'" + echo -n "as DN for storage of the Qmail control information)? [Y/n] " + read s + if [ "$s" = "n" -o "$s" = "N" ]; then + echo "Oki, then please give me the correct Base DN to search for the QMail control" + echo -n "information: " + read SUFFIX + fi + fi + fi + if [ "$SUFFIX" = "" ]; then + echo "Please give me the correct Base DN to search for the QMail control information" + echo -n ": " + read SUFFIX + fi +fi +LDAPCONTROLDN="cn=$FQDN,$SUFFIX" + +# FILE: ldaplogin Username for the LDAP server connection +# FILE: ldappassword Password for the LDAP server connection +echo +echo "Does the SLAPD server allow anonymous connects to retrive the uid/homedirectory etc?" +echo -n "(Most servers do, and if you do not know, please answer Y here) [Y/n] " +read s +if [ "$s" = "n" -o "$s" = "N" ]; then + echo "Oki, give me the (full) Bind DN for the LDAP server: " + echo "NOTE: This must be a full bind dn (something like 'cn=admin,ou=People,o=Internet Pipeline,c=CH'" + echo -n ": " + read LDAPLOGIN + echo "Now I need the password to: " + read LDAPPASSWORD +else + LDAPLOGIN="" + LDAPPASSWORD="" +fi + +# FILE: ldaplocaldelivery Use the ~users/get-pw mechanism if the LDAP lookup finds nothing +echo +echo "There is a option to have a external script (~users/get-pw) that can be used if the LDAP lookup" +echo -n "doesn't find any matching entry in the database. Do you want to use that? [y/N] " +read s +if [ "$s" = "y" -o "$s" = "Y" ]; then + LDAPLOCALLOOKUP=1 +else + LDAPLOCALLOOKUP=0 +fi + +# FILE: ldapdefaultquota The default amount of space one user can use +echo +echo -n "Do you want to impose a default mail quota for you users (can be overridden by mailQuota)? [y/N] " +read s +if [ "$s" = "y" -o "$s" = "Y" ]; then + echo -n "Very well then, how much (in KByte)? " + read LDAPDEFAULTQUOTA +else + LDAPDEFAULTQUOTA="" +fi + +# FILE: ldapdefaultdotmode The default interpretation of .qmail files +# ??????? + +# FILE: ldapmessagestore The default added path for mailMessageStore/homedirectory without trailing / +echo +echo -n "What path should be added to the users homedirectory for delivering the mail to? [] " +read s +if [ "$s" = "" ]; then + LDAPMESSAGESTORE= +else + LDAPMESSAGESTORE=$s +fi + +echo +echo "Are you planning on using QmailLDAP in a virtual user environment (ie, to not deliver" +echo -n "to real users) [y/N] " +read s +if [ "$s" = "y" -o "$s" = "Y" ]; then + # FILE: ldapuid The default UID used in virtual users environments + echo "What chould the default user ID be, for use in a virtual user environment (optional)" + echo -n "If supplied, this must be above 100 (Press to not use it) " + read s + if [ "$s" = "" ]; then + LDAPUID="" + else + LDAPUID=$s + fi + + # FILE: ldapgid The default GID used in virtual users environments + echo "What chould the default group ID be, for use in a virtual user environment (optional)" + echo -n "If supplied, this must be above 100 (Press to not use it) " + read s + if [ "$s" = "" ]; then + LDAPGID="" + else + LDAPGID=$s + fi +else + LDAPUID="" + LDAPGID="" +fi + +# FILE: dirmaker Absolute path to your program/script that creates missing homedirs +echo +echo -n "Are you planning on having missing homedirectories automaticly created with a script? [y/N] " +read s +if [ "$s" = "y" -o "$s" = "Y" ]; then + echo -n "Do you already Have a script, or do you want me to Create one for you (a very simple one)? [h/C] " + read s + if [ "$s" = "h" -o "$s" = "H" ]; then + echo -n "Then I would like to know WHERE that script is located in the filesystem: " + read DIRMAKER + else + echo "I will create the script ~qmaild/bin/create_homedir and use that for creating missing homedirs" + echo "at maildelivery time." + DIRMAKER="`dirname ~qmaild/bin/create_homedirs`/create_homedirs" + CREATE_DIRMAKER=1 + fi +else + DIRMAKER="" + CREATE_DIRMAKER=0 +fi + +# -------------------------------------------------------------------------------------------------- + +# Double check... +echo +echo +echo "Is the choosen configuration correct?" +echo "LDAPSERVER: $LDAPSERVER" +echo "LDAPBASEDN: $LDAPBASEDN" +if [ "$USE_LDAPCONTROLS" = 1 ]; then + echo "LDAPCONTROLDN: $LDAPCONTROLDN" + if [ "$CREATE_LDIF" = 1 ]; then + echo "Create LDIF file: Yes" + else + echo "Create LDIF file: No" + fi +fi +echo "LDAPLOGIN: $LDAPLOGIN" +echo "LDAPPASSWORD: $LDAPPASSWORD" +if [ "$LDAPLOCALLOOKUP" = 1 ]; then + echo "LDAPLOCALLOOKUP: Yes" +else + echo "LDAPLOCALLOOKUP: No" +fi +echo "LDAPDEFAULTQUOTA: $LDAPDEFAULTQUOTA" +if [ "$LDAPMESSAGESTORE" != "" ]; then + echo "LDAPMESSAGESTORE: $LDAPMESSAGESTORE" +else + echo "LDAPMESSAGESTORE: " +fi +echo "LDAPUID: $LDAPUID" +echo "LDAPGID: $LDAPGID" +echo "DIRMAKER: $DIRMAKER" + +echo +echo -n "Okay? [Y/n] " +read s +if [ "$s" = "n" -o "$s" = "N" ]; then + echo "Oki, I'm out'a here. Please run the script again..." + exit 1 +fi + +cd /var/qmail/control || exit 1 + +echo > ldapserver "$LDAPSERVER" +if [ "$LDAPLOGIN" != "" ]; then echo > ldaplogin "$LDAPLOGIN"; fi +if [ "$LDAPPASSWORD" != "" ]; then echo > ldappassword "$LDAPPASSWORD"; fi +if [ "$USE_LDAPCONTROLS" = 1 ]; then + echo > ldapcontroldn "$LDAPCONTROLDN" + + echo > /root/qmail-ldap.ldif "dn: $LDAPCONTROLDN" + echo >> /root/qmail-ldap.ldif "objectClass: top" + echo >> /root/qmail-ldap.ldif "objectClass: qmailControl" + echo >> /root/qmail-ldap.ldif "cn: $FQDN" + + if [ "$LDAPBASEDN" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapBaseDn: $LDAPBASEDN" + fi + if [ "$LDAPDEFAULTQUOTA" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapDefaultQuota: $LDAPDEFAULTQUOTA" + fi + if [ "$LDAPMESSAGESTORE" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapMessageStore: $LDAPMESSAGESTORE" + fi + if [ "$LDAPPASSWDAPPEND" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapPasswdAppend: $LDAPPASSWDAPPEND" + fi + if [ "$LDAPUSERNAME" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapUserName: $LDAPUSERNAME" + fi + if [ "$LDAPUID" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapUid: $LDAPUID" + fi + if [ "$LDAPGID" != "" ]; then + echo >> /root/qmail-ldap.ldif "ldapGid: $LDAPGID" + fi + if [ "$DIRMAKER" != "" ]; then + echo >> /root/qmail-ldap.ldif "dirMaker: $DIRMAKER" + fi + + # Now, some perl hacking! I don't know shell that well... :) + cd /var/qmail/control && find -type f -maxdepth 1 | \ + perl -e ' +while(! eof(STDIN) ) { + $file = ; + next if($file =~ /me/); + next if($file =~ /ldap/); + chomp($file); + $file =~ s@./@@g; + open(FILE, "$file") || die "Oups, $!\n"; + while(! eof(FILE) ) { + $line = ; + print "$file: $line"; + } + close(FILE); +}' >> /root/qmail-ldap.ldif + + if [ "$DOMA" != "" ]; then + if ! `grep -q '^locals: $DOMA$' /root/qmail-ldap.ldif`; then + # Make sure that the domainname (ONLY!) is in the db... + echo "locals: $DOMA" >> /root/qmail-ldap.ldif + fi + fi +else + echo > ldapbasedn "$LDAPBASEDN" +fi + +# -------------------------------------------------------------------------------------------------- + +# Create the dirmaker script? +if [ "$CREATE_DIRMAKER" == 1 ]; then + # Yes + mkdir -p `dirname $DIRMAKER` + cat > $DIRMAKER < 5) { + open(UPTIME, "/usr/bin/uptime |") + || die("Can't get uptime, $!\n"); + $line = ; chomp($line); + $load = (split(' ', $line))[9]; + $load = (split('\.', $load))[0]; + close(UPTIME); + + if($load > 5) { + sleep(5); + } +} +print "done.\n"; + +system("/etc/init.d/sendmail start"); Index: qmail-1.03/qmail-ldap-control/qmail-maildrop =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/qmail-maildrop @@ -0,0 +1,12 @@ +#!/bin/sh + +export MAILDIR=$PWD +export TMPHOMEDIR=$MAILDIR +export HOME=$MAILDIR +/usr/bin/preline /usr/bin/maildrop && exit 0 + +# check if maildrop returned EX_TEMPFAIL (75) +[ $? = 75 ] && exit 111 + +# otherwise return a permanent error +exit 100 Index: qmail-1.03/qmail-ldap-control/qmail-queue.rules =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/qmail-queue.rules @@ -0,0 +1,13 @@ +# No Qmail-Scanner at all for mail from 127.0.0.1 - I trust my users... +127.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-queue" +# +# Use Qmail-Scanner without SpamAssassin on any mail from the local network +# [it triggers SpamAssassin via the presence of the RELAYCLIENT var] +# +# Note: I have tree MX. It's possible that a message come from one of the other +# MX'es, hence uncomment this!!! /Turbo +#212.214.70.:allow,RELAYCLIENT="",RBLSMTPD="",QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl",SMTPAUTH="TLSREQUIRED" +# +# Use Qmail-Scanner with SpamAssassin on any mail from the rest of the world. +# Also REQUIRE the use of TLS when authenticating. +:allow,QMAILQUEUE="/var/qmail/bin/qmail-scanner-queue.pl",SMTPAUTH="TLSREQUIRED" Index: qmail-1.03/qmail-ldap-control/qmailControl.schema =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/qmailControl.schema @@ -0,0 +1,394 @@ +# Created by Turbo Fredriksson +# - Original creation (dd/mm/yyyy) +# +# Modified by Leonardo Fialho +# - Now it works with OpenLDAP 2.x OIDs (08/10/2002) +# +# Attributes that are qmail specific + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.13 NAME 'badMailFrom' + DESC 'Unacceptable envelope sender addresses.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.14 NAME 'bounceFrom' + DESC 'Bounce username' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.15 NAME 'bounceHost' + DESC 'Bounce host' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.16 NAME 'concurrencyLocal' + DESC 'Maximum number of simultaneous local delivery attempts.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.17 NAME 'concurrencyRemote' + DESC 'Maximum number of simultaneous remote delivery attempts.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.18 NAME 'defaultDomain' + DESC 'Default domain name.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.19 NAME 'defaultHost' + DESC 'Default host name.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.20 NAME 'dataBytes' + DESC 'Maximum number of bytes allowed in a message, or 0 for no limit.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.21 NAME 'doubleBounceHost' + DESC 'Double-bounce host.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.22 NAME 'doubleBounceTo' + DESC 'User to receive double-bounces.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.23 NAME 'envNoAtHost' + DESC 'Presumed domain name for addresses without @ signs.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.24 NAME 'heloHost' + DESC 'Host name used to say hello to the remote SMTP server.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.25 NAME 'idHost' + DESC 'Host name for Message-IDs.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.26 NAME 'localIpHost' + DESC 'Replacement host name for local IP addresses.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.27 NAME 'locals' + DESC 'List of domain names that the current host receives mail for.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.28 NAME 'moreRcptHosts' + DESC 'Extra allowed RCPT domains.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.29 NAME 'percentHack' + DESC 'List of domain names where the percent hack is applied.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.30 NAME 'plusDomain' + DESC 'Plus domain name.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.31 NAME 'qmqpServers' + DESC 'IP addresses of QMQP servers.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.32 NAME 'queueLifetime' + DESC 'Number of seconds a message can stay in the queue.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.33 NAME 'rcptHosts' + DESC 'Allowed RCPT domains.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.34 NAME 'smtpGreeting' + DESC 'SMTP greeting message.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.35 NAME 'smtpRoutes' + DESC 'Artificial SMTP routes.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.36 NAME 'timeoutConnect' + DESC 'Number of seconds qmail-remote will wait for the remote SMTP server to accept a connection.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.37 NAME 'timeoutRemote' + DESC 'Number of seconds qmail-remote will wait for each response from the remote SMTP server.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.38 NAME 'timeoutSmtpd' + DESC 'Timeout for each new buffer of data from the remote SMTP client.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.39 NAME 'virtualDomains' + DESC 'List of virtual users or domains.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +# Attributes from qmail-ldap + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.40 NAME 'ldapBaseDN' + DESC 'The base DN from where the search in the LDAP tree begins.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.41 NAME 'ldapLogin' + DESC 'Username for the LDAP server connection.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.42 NAME 'ldapPassword' + DESC 'Password for the LDAP server connection.' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.43 NAME 'ldapLocalDelivery' + DESC 'If to do a lookup on the local passwd file.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.44 NAME 'ldapRebind' + DESC 'Use the possibility of rebinding to the ldap-server to compare pop3 and imap passwords.' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.45 NAME 'ldapCluster' + DESC 'Turn clustering on and off.' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +# ldapDefaultQuota is no longer supported from qmail-ldap 20030901 on, +# use defaultQuotaSize and defaultQuotaCount instead. +attributetype ( 1.3.6.1.4.1.7006.1.2.1.46 NAME 'ldapDefaultQuota' + DESC 'The default amount of disk space the user can use.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.47 NAME 'ldapDefaultDotMode' + DESC 'The default interpretation of .qmail files' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.48 NAME 'ldapMessageStore' + DESC 'The default prefix for pathes in mailMessageStore.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.49 NAME 'ldapUid' + DESC 'The default UID used in virtual users environments.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.50 NAME 'ldapGid' + DESC 'The default GID used in virtual users environments.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.51 NAME 'customBounceText' + DESC 'Additional custom text in bounce messages.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{1024} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.52 NAME 'quotaWarning' + DESC 'Custom text in quota warning message.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{1024} SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.53 NAME 'tarpitCount' + DESC 'Number of RCPT TOs you accept before you start tarpitting.' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.54 NAME 'tarpitDelay' + DESC 'Number of seconds of delay to introduce after each subsequent RCPT TO' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.55 NAME 'badRcptTo' + DESC 'List of recipient addresses that should be rejected.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.56 NAME 'dirMaker' + DESC 'Absolute path to your program/script that creates missing homedirs.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.57 NAME 'ldapServer' + DESC 'LDAP Server address.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +# Attributes from TLS + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.58 NAME 'tlsClients' + DESC 'This email-address is logged in the headers.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +# Support for this have to be coded first +attributetype ( 1.3.6.1.4.1.7006.1.2.1.59 NAME 'smtpCert' + DESC 'Path to the cert.pem file.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) +# -> Example: /var/qmail/control/cert.pem +# +#attributetype ( 1.3.6.1.4.1.7006.1.2.1.60 NAME 'certificateFile' +# DESC 'Path to the cert.pem file.' +# EQUALITY caseExactIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) +# -> Example: /var/qmail/control/rsa512.pem +# +#attributetype ( 1.3.6.1.4.1.7006.1.2.1.61 NAME 'clientCAFile' +# DESC 'Path to the certificate CA list file.' +# EQUALITY caseExactIA5Match +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) +# -> Example: /var/qmail/control/clientca.pem +# + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.62 NAME 'pbsServers' + DESC 'List of IP addresses of running pbsdbd servers.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.63 NAME 'pbsIp' + DESC 'pbsdbd server address.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.64 NAME 'pbsPort' + DESC 'Port where all pbsdbd servers are listening on' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.65 NAME 'pbsSecret' + DESC 'Shared secret used by pbsadd and pbsdbd to authenticate the client.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.66 NAME 'pbsCacheSize' + DESC 'Size in bytes used for the cache.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.67 NAME 'pbsTimeOut' + DESC 'Timeout in seconds until entries in the cache are invalidated.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.68 NAME 'pbsEnv' + DESC 'Additional environment variables to include.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.69 NAME 'defaultQuotaSize' + DESC 'The default amount of disk space the user can use.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.70 NAME 'defaultQuotaCount' + DESC 'The default amount of mails the user can have in the mailbox.' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.71 NAME 'ldapClusterHosts' + DESC 'List of host names that are part of the mail cluster.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.72 NAME 'ldapTimeOut' + DESC 'Time (in seconds) to wait for response from LDAP server.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.73 NAME 'outgoingIp' + DESC 'IP address qmail-remote should bind to.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.74 NAME 'smtpClusterCookie' + DESC 'Random string to identify the SMTP/MX cluster to avoid looping.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.75 NAME 'goodMailAddr' + DESC 'Local recipients that are always accepted.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.76 NAME 'bounceMaxBytes' + DESC 'The maximal number of bytes to be included in a bounce message.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.77 NAME 'rblList' + DESC 'Realtime Blackhole List (RBL) servers' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.78 NAME 'bigBrother' + DESC 'Transparent copy all mail to/from address1 to address2, separated with colon' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.79 NAME 'relayMailFrom' + DESC 'envelope sender addresses that are allowed to relay through this server' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.80 NAME 'maxRcptCount' + DESC 'Maximum number of RCPT TOs' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.81 NAME 'qmqpcIp' + DESC 'The IP qmail-qmqpc should bind to' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.82 NAME 'defaultDelivery' + DESC 'Default delivery mode used by and only by the startup scripts.' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.7006.1.2.1.83 NAME 'ldapObjectClass' + DESC 'The ldap objectclass the search will be limited to' + EQUALITY caseIgnoreIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) + +# Object Class Definitions + +objectclass ( 1.3.6.1.4.1.7006.1.2.2.2 NAME 'qmailControl' + DESC 'QMail-LDAP Server Control Information' + SUP top STRUCTURAL + MUST cn + MAY ( badMailFrom $ bounceFrom $ bounceHost $ concurrencyLocal $ + concurrencyRemote $ defaultDomain $ defaultHost $ dataBytes $ + doubleBounceHost $ doubleBounceTo $ envNoAtHost $ heloHost $ + idHost $ localIpHost $ locals $ moreRcptHosts $ percentHack $ + plusDomain $ qmqpServers $ queueLifetime $ rcptHosts $ + smtpGreeting $ smtpRoutes $ timeoutConnect $ timeoutRemote $ + timeoutSmtpd $ virtualDomains $ ldapBaseDN $ ldapLogin $ + ldapPassword $ ldapLocalDelivery $ ldapRebind $ ldapCluster $ + ldapDefaultQuota $ defaultQuotaSize $ defaultQuotaCount $ + ldapDefaultDotMode $ ldapMessageStore $ ldapUid $ ldapGid $ + customBounceText $ quotaWarning $ tarpitCount $ tarpitDelay $ + badRcptTo $ dirMaker $ ldapServer $ tlsClients $ pbsServers $ + pbsIp $ pbsPort $ pbsSecret $ pbsCacheSize $ pbsTimeOut $ + pbsEnv $ smtpCert $ ldapClusterHosts $ ldapTimeOut $ + outgoingIp $ smtpClusterCookie $ goodMailAddr $ bounceMaxBytes $ + rblList $ bigBrother $ relayMailFrom $ maxRcptCount $ + qmqpcIp $ defaultDelivery $ ldapObjectClass ) ) Index: qmail-1.03/qmail-ldap-control/rc.debian =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/rc.debian @@ -0,0 +1,164 @@ +#!/bin/bash -e +# +# /etc/init.d/qmail : start or stop the qmail mail subsystem. +# +# Written by Christian Hudon +# Currently maintained by Jon Marler +# +# Configuration +# + +export PATH=$PATH:/var/qmail/bin + +# set default delivery method + +#alias_empty="|/usr/sbin/qmail-procmail" # procmail delivery to /var/spool/mail +#alias_empty="./Maildir/" # This uses qmail prefered ~/Maildir/ directory +# # You may want to maildirmake /etc/skel/Maildir +#alias_empty="./Mailbox" # This uses Mailbox file in users $HOME +alias_empty="./" # If doing deliveries directly to the message + # store directly. +#alias_empty="|/usr/sbin/qmail-maildrop" + +logger="| splogger qmail" +#logger="| accustamp >>/var/log/qmail.log" # If you have accustamp installed. +#logger=">>/var/log/qmail.log" # Does not give timing info. + +# If you uncommented one of the lines that appends to /var/log/qmail.log, you +# need to uncomment the following two lines. +touch /var/log/qmail.log +chown qmaill.www-data /var/log/qmail.log + +# +# End of configuration +# + +test -x /var/qmail/bin/qmail-start || exit 0 +test -x /var/qmail/bin/qmail-send || exit 0 + +start_smtpd () { + tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp + tcprules /etc/tcp.qmqp.cdb /etc/tcp.qmqp.tmp < /etc/tcp.qmqp + + # prevent denial-of-service attacks, with ulimit + ulimit -v 65536 + sh -c "start-stop-daemon --start --quiet --user qmaild \ + --exec /usr/bin/tcpserver -- \ + -u qmaild -g 65534 -x /etc/tcp.smtp.cdb 0 smtp \ + /var/qmail/bin/qmail-smtpd \ + /var/qmail/bin/auth_smtp /bin/true \ + 2>&1 $logger &" + echo -n "qmail-smtpd " +} + +start_local () { + sh -c "start-stop-daemon --start --quiet --user qmails \ + --exec /var/qmail/bin/qmail-send \ + --startas /var/qmail/bin/qmail-start -- \"$alias_empty\" $logger &" + echo -n "qmail-start " +} + +start_pop3 () { +# sh -c "start-stop-daemon --start --quiet --user root \ +# --exec /usr/bin/tcpserver -- \ +# 0 pop-3 /var/qmail/bin/qmail-popup `hostname`.`dnsdomainname` \ +# /var/qmail/bin/auth_pop /var/qmail/bin/qmail-pop3d Maildir &" + /usr/bin/tcpserver 0 pop3 /var/qmail/bin/qmail-popup `hostname`.`dnsdomainname` \ + /var/qmail/bin/auth_pop /var/qmail/bin/qmail-pop3d ./ & + echo -n "qmail-pop3d " +} + +start_qmqpd () { + sh -c "start-stop-daemon --start --quiet --user root \ + --exec /usr/bin/tcpserver x /etc/qmqp.cdb -u 64011 -g 65534 \ + 0 628 /var/qmail/bin/qmail-qmqpd &" + echo -n "qmail-qmqpd " +} + +case "$1" in + smtpd) + echo -n "Starting mail-transfer agents: " + start_smtpd + echo "." + ;; + local) + echo -n "Starting mail-transfer agents: " + start_local + echo "." + ;; + start) + echo -n "Starting mail-transfer agents: " + + start_local + start_smtpd + + # Uncomment the following lines to automatically start the pop3 server + start_pop3 + + # Uncomment the following lines to automaticly start the qmqpd server + # start_qmqpd + + echo "." + ;; + stop) + echo -n "Stopping mail-transfer agent: qmail" + if [ "`pidof /var/qmail/bin/qmail-send`" ] ; then + start-stop-daemon --user qmails --stop --quiet --oknodo --exec /var/qmail/bin/qmail-send + start-stop-daemon --user qmaild --stop --quiet --oknodo --exec /usr/bin/tcpserver + # Uncomment the following line if you have enabled the pop3 server + #start-stop-daemon --user root --stop --quiet --oknodo --exec /usr/bin/tcpserver + + # Wait until the timeout for qmail processes to die. + count=120 + numdots=0 + while ([ $count != 0 ]) do + let count=$count-1 + if [ "`pidof /var/qmail/bin/qmail-send`" ] ; then + echo -n . + let numdots=$numdots+1 + sleep 1 + else + count=0 + fi + done + + # If it's not dead yet, kill it. +# if [ "`pidof /var/qmail/bin/qmail-send`" ] ; then +# echo -n " TIMEOUT!" +# kill -KILL `pidof /var/qmail/bin/qmail-send` +# else + case $numdots in + 0) echo "." ;; + 1) echo ;; + *) echo " done." ;; + esac +# fi + else + echo " not running."; + fi + + killall tcpserver + ;; + restart) + $0 stop + $0 start + ;; + reload|force-reload) + echo "Reloading 'locals' and 'virtualdomains' control files." + start-stop-daemon --stop --quiet --oknodo --signal HUP --exec /var/qmail/bin/qmail-send + ;; + flush) + /var/qmail/bin/qmail-tcpok + start-stop-daemon --stop --quiet --oknodo --signal ALRM --exec /var/qmail/bin/qmail-send + echo "Queue flushed." + ;; + stat) + /var/qmail/bin/qmail-qread + /var/qmail/bin/qmail-qstat + ;; + *) + echo 'Usage: /etc/init.d/qmail {smtpd|start|stop|restart|reload|flush|stat}' + exit 1 +esac + +exit 0 Index: qmail-1.03/qmail-ldap-control/rc.turbo =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/rc.turbo @@ -0,0 +1,185 @@ +#!/bin/bash -e +# +# /etc/init.d/qmail : start or stop the qmail mail subsystem. +# +# Written by Christian Hudon +# Currently maintained by Jon Marler +# +# Rewritten slightly by Turbo Fredriksson +# for use with QmaiLDAP/Controls package. + +# Please do not touch this file. Change /etc/default/qmail +# instead. + +export PATH=$PATH:/var/qmail/bin + +test -x /var/qmail/bin/qmail-start || exit 0 +test -x /var/qmail/bin/qmail-send || exit 0 + +if [ -f /etc/default/qmail ]; then + . /etc/default/qmail +else + # Some defaults... + alias_empty="|/usr/sbin/qmail-maildrop" + keep_size=1000000 ; keep_count=20 +fi + +logger_smtp="| multilog t s$keep_size n$keep_count /var/log/qmail/smtp" +logger_send="| multilog t s$keep_size n$keep_count /var/log/qmail/send" +logger_qmqp="| multilog t s$keep_size n$keep_count /var/log/qmail/qmqp" +mkdir -p /var/log/qmail/{send,smtp,qmqp} + +start_smtpd () { + [ -f /etc/tcp.smtp ] && tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp + [ -f /etc/tcp.qmqp ] && tcprules /etc/tcp.qmqp.cdb /etc/tcp.qmqp.tmp < /etc/tcp.qmqp + + # prevent denial-of-service attacks, with ulimit + ulimit -v 65536 + + if [ ! -z "$POPBEFORESMTP" ]; then + # Use POP before SMTP + sh -c "start-stop-daemon --start --quiet --user qmaild \ + --exec /usr/bin/tcpserver -- $concurrency_smtp \ + -v -u qmaild -g 65534 -x /etc/tcp.smtp.cdb 0 smtp \ + /usr/bin/pbscheck /var/qmail/bin/qmail-smtpd \ + 2>&1 $logger_smtp &" + elif [ ! -z "$SMTPAUTH" ]; then + sh -c "start-stop-daemon --start --quiet --user qmaild \ + --exec /usr/bin/tcpserver -- $concurrency_smtp \ + -v -u qmaild -g 65534 -x /etc/tcp.smtp.cdb 0 smtp \ + /var/qmail/bin/qmail-smtpd /var/qmail/bin/auth_smtp \ + /bin/true 2>&1 $logger_smtp &" + else + sh -c "start-stop-daemon --start --quiet --user qmaild \ + --exec /usr/bin/tcpserver -- $concurrency_smtp \ + -v -u qmaild -g 65534 -x /etc/tcp.smtp.cdb 0 smtp \ + /var/qmail/bin/qmail-smtpd 2>&1 $logger_smtp &" + fi + echo -n "qmail-smtpd " +} + +start_local () { + sh -c "start-stop-daemon --start --quiet --user qmails \ + --exec /var/qmail/bin/qmail-send \ + --startas /var/qmail/bin/qmail-start -- \"$alias_empty\" $logger_send &" + echo -n "qmail-start " +} + +start_pop3 () { + if [ ! -z "$POPBEFORESMTP" ]; then + # Use POP before SMTP + /usr/bin/tcpserver $concurrency_pop3 0 pop3 \ + /var/qmail/bin/qmail-popup `hostname` \ + /var/qmail/bin/auth_pop /var/qmail/bin/pbsadd \ + /var/qmail/bin/qmail-pop3d ./ & + else + /usr/bin/tcpserver $concurrency_pop3 0 pop3 \ + /var/qmail/bin/qmail-popup `hostname` \ + /var/qmail/bin/auth_pop /var/qmail/bin/qmail-pop3d ./ & + fi + echo -n "qmail-pop3d " +} + +start_qmqpd () { + sh -c "start-stop-daemon --start --quiet --user qmaild \ + --exec /usr/bin/tcpserver -- $concurrency_qmqpd -v \ + -u qmaild -g 65534 -x /etc/tcp.qmqp.cdb 0 628 \ + /var/qmail/bin/qmail-qmqpd 2>&1 $logger_qmqp &" + echo -n "qmail-qmqpd " +} + +start_pbsdbd () { + /var/qmail/bin/pbsdbd & + echo -n "pbsdbd " +} + +case "$1" in + smtpd) + echo -n "Starting mail-transfer agents: " + start_smtpd + echo "." + ;; + local) + echo -n "Starting mail-transfer agents: " + start_local + echo "." + ;; + start) + echo -n "Starting mail-transfer agents: " + + [ ! -z "$STARTLOCAL" ] && start_local + [ ! -z "$STARTSMTPD" ] && start_smtpd + + [ ! -z "$POPBEFORESMTP" ] && start_pbsdbd + [ ! -z "$QLDAPCLUSTER" ] && start_qmqpd + [ ! -z "$STARTPOP3" ] && start_pop3 + + echo "." + ;; + stop) + echo -n "Stopping mail-transfer agent: qmail" + if [ "`pidof /var/qmail/bin/qmail-send`" ] ; then + start-stop-daemon --user qmails --stop --quiet --oknodo --exec /var/qmail/bin/qmail-send + start-stop-daemon --user qmaild --stop --quiet --oknodo --exec /usr/bin/tcpserver + + [ ! -z "$STARTPOP3" ] && start-stop-daemon --user root --stop --quiet --oknodo --exec /usr/bin/tcpserver + + # Wait until the timeout for qmail processes to die. + count=120 + numdots=0 + while ([ $count != 0 ]) do + let count=$count-1 + if [ "`pidof /var/qmail/bin/qmail-send`" ] ; then + echo -n . + let numdots=$numdots+1 + sleep 1 + else + count=0 + fi + done + + # If it's not dead yet, kill it. +# if [ "`pidof /var/qmail/bin/qmail-send`" ] ; then +# echo -n " TIMEOUT!" +# kill -KILL `pidof /var/qmail/bin/qmail-send` +# else + case $numdots in + 0) echo "." ;; + 1) echo ;; + *) echo " done." ;; + esac +# fi + else + echo " not running."; + fi + + if [ "`pidof /var/qmail/bin/pbsdbd`" ] ; then + killall pbsdbd + fi + + killall tcpserver + ;; + restart) + $0 stop + sleep 2 + $0 start + ;; + reload|force-reload) + echo "Reloading 'locals' and 'virtualdomains' control files." + start-stop-daemon --stop --quiet --oknodo --signal HUP --exec /var/qmail/bin/qmail-send + ;; + flush) + /var/qmail/bin/qmail-tcpok + start-stop-daemon --stop --quiet --oknodo --signal ALRM --exec /var/qmail/bin/qmail-send + echo "Queue flushed." + ;; + stat) + /var/qmail/bin/qmail-qread + /var/qmail/bin/qmail-qstat + ;; + *) + echo 'Usage: /etc/init.d/qmail {smtpd|start|stop|restart|reload|flush|stat}' + exit 1 +esac + +exit 0 Index: qmail-1.03/qmail-ldap-control/test_smtp.sh =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldap-control/test_smtp.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +if [ "$#" != 0 ]; then + CLEAR=1 +fi + +if [ "$#" != 0 ]; then + echo "Clearing queue, mailbox and restarting slapd and qmail..." + find /var/qmail/queue/ -type f -name '[0-9]*' | xargs --no-run-if-empty rm + rm /var/log/qmail/*/* + /etc/init.d/slapd restart > /dev/null 2>&1 + /etc/init.d/qmail restart > /dev/null 2>&1 + + exit 0 +fi + +todo=`find /var/qmail/queue/todo -type f -name '[0-9]*' | wc -l` +printf "Mails in todo: %4d\n" $todo + +local=`find /var/qmail/queue/local -type f -name '[0-9]*' | wc -l` +printf "Mails in local: %4d\n" $local + +printf "\n" + +slapds=`/bin/ps axwww | grep slapd | grep -v grep | wc -l` +printf "SLAPDs running: %4d\n" $slapds + +smtpds=`/bin/ps axwww | grep bin/qmail-smtp | egrep -v 'grep|bin/pbscheck' | wc -l` +printf "SMTPDs running: %4d\n" $smtpds + +if [ -f /var/log/qmail/smtp/current ]; then + printf "\n" + + set -- `grep 'tcpserver: ok' /var/log/qmail/smtp/current | tai64nlocal | sort | head -n1 | sed 's@ tcpserver.*@@'` + beg=`echo $2 | sed 's@\..*@@'` + + set -- `grep 'tcpserver: end' /var/log/qmail/smtp/current | tai64nlocal | sort | tail -n1 | sed 's@ tcpserver.*@@'` + end=`echo $2 | sed 's@\..*@@'` + + printf "First delivery: %s\n" $beg + printf "Last delivery: %s\n" $end +fi Index: qmail-1.03/qmail-ldap.h =================================================================== --- qmail-1.03.orig/qmail-ldap.h +++ qmail-1.03/qmail-ldap.h @@ -40,6 +40,10 @@ */ #define LDAP_CATCH_ALL "catchall" +/* this is the default dn to check if a attribute can't be found + * in the real dn for this host. */ +#define CONTROL_CATCH_ALL "default" + /* triger level for quotawarning (0-100) */ #define QUOTA_WARNING_LEVEL 70 @@ -92,17 +96,29 @@ /********************************************************************* ldap variables used in qmail-lspawn and auth_* *********************************************************************/ +#ifdef USE_RFC822 +#define LDAP_MAIL "mailLocalAddress" +#define LDAP_FORWARDS "mailRoutingAddress" +#else #define LDAP_MAIL "mail" +#endif #define LDAP_MAILALTERNATE "mailAlternateAddress" +#ifdef USE_RFC2307 +#define LDAP_QMAILUID "uidNumber" +#define LDAP_QMAILGID "gidNumber" +#else #define LDAP_QMAILUID "qmailUID" #define LDAP_QMAILGID "qmailGID" +#endif #define LDAP_MAILSTORE "mailMessageStore" #define LDAP_HOMEDIR "homeDirectory" #define LDAP_QUOTA "mailQuota" #define LDAP_QUOTA_SIZE "mailQuotaSize" #define LDAP_QUOTA_COUNT "mailQuotaCount" #define LDAP_MAXMSIZE "mailSizeMax" +#if !defined(USE_RFC822) #define LDAP_FORWARDS "mailForwardingAddress" +#endif #define LDAP_PROGRAM "deliveryProgramPath" #define LDAP_MAILHOST "mailHost" #define LDAP_MODE "deliveryMode" Index: qmail-1.03/qmail-ldapctrld-test.c =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldapctrld-test.c @@ -0,0 +1,33 @@ +/* Copyright: 1995-12-20 Lars Brinkhoff */ +#include +#include + +int main(int argc, char *argv[]) +{ + int r, s; + char buf; + struct sockaddr_un addr; + + if(argc != 2) { + write(1, "usage error\n", 12); + exit(1); + } + + addr.sun_family = PF_LOCAL; + strcpy(addr.sun_path, "/var/run/qldap-ctrld"); + + s = socket(addr.sun_family, SOCK_STREAM, 0); + if(s == -1) { + perror("socket"); + exit(1); + } + + r = connect(s, (struct sockaddr *)&addr, sizeof(addr)); + if(r == -1) { + perror("connect"); + exit(1); + } + + write(s, argv[1], 4); +} +/* Club to death: "Club to death" (jajamen, har hort den forut) */ Index: qmail-1.03/qmail-ldapctrld.c =================================================================== --- /dev/null +++ qmail-1.03/qmail-ldapctrld.c @@ -0,0 +1,219 @@ +/* The idea with this program is to be started (first) from + * 'qmail-start' as all the other Qmail daemons. + * + * - The program will create a socket which it will listen on. + * - When a connection/command comes in on this socket, it will + * check it's (memory!) cache for this value. If it doesn't + * have it, it will request the WHOLE object from the LDAP + * server (multiple ones should be allowed, tried in turn). + * - It will be running as qmaild:qmail, and the socket will be + * readable only the user root and the group (mode 0660). + * + * To use this daemon, add USE_CTRLD to LDAPFLAGS in the + * Makefile, and create the file ~control/ldapctrld with + * the (full) path to the socket. + * + * !! THIS PROGRAM IS BARLEY STARTED - NOTHING WORKS YET !! + * + * There is absolutly NO point in compiling it, unless you care + * to develop on it... + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include some LDAP magic... */ +#include +#include +#include "qmail-ldap.h" +#include "qldap-debug.h" +#include "qldap-errno.h" +#include "qlx.h" +#include "qldap.h" +#include "auto_qmail.h" +#include "stralloc.h" +#include "fd.h" +#include "fork.h" +#include "error.h" +#include "output.h" +#include "read-ctrl.h" + +qldap *q; + +/* These are defined in every (!!) file that tries to open a file + * in ~control/. */ +extern stralloc ldap_me; +extern stralloc ldap_server; +extern stralloc ldap_controldn; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_port; + +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; + +stralloc ldap_socket = {0}; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#include +#include +#include + +#include "subfd.h" +#include "sgetopt.h" + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_ALL) +static unsigned sasl_flags = LDAP_SASL_AUTOMATIC; +#endif +#endif + +#define BUFLEN 4 + +void +usage(void) +{ + output(subfderr, + "usage:" + "\t%s [-d] [-s path]\n", optprogname); + output(subfderr, + "options:\n" + "\t-d\t\tDon't detach from terminal (debug mode)\n" + "\t-s path\t\tFull path to UNIX domain socket for connections\n" + "\t\t\tDEFAULT: whatever specified in ~control/ldapctrld\n"); + _exit(1); +} + +stralloc * +qldapctrl_retreive_value(char *fn) +{ + return((stralloc *)NULL); +} + +int main(int argc, char **argv) +{ + struct sockaddr_un addr; + char *sock_path = 0; + char buf[5]; + int do_fork = 1, opt, sock, addrlen; + int i, fddir, ns, r; + pid_t pid; + + while ((opt = getopt(argc, argv, "dhs:")) != opteof) + switch (opt) { + case 'd': + do_fork = 0; + break; + case 's': + if (!optarg) + usage(); + sock_path = optarg; + break; + case 'h': + usage(); + break; + } + + /* Detach from terminal (if not debugging) */ + if(do_fork) { + fflush( NULL ); + if(fork() != 0) { + /* This is the mother process -> DIE, DIE */ + _exit(0); + } + } else + log_init(STDERR, -1, 0); + + /* Read controls */ + /* ----------------- */ + logit(32, "reading controls: "); + if (read_controls(ctrls) != 0) { + logit(1, "QmailLDAP/Ctrld: unable to open current directory"); + _exit(1); + } + logit(32, "done.\n"); + + logit(32, "reading control/ldapctrld: "); + if(!sock_path) { + if (control_rldef(&ldap_socket,"control/ldapctrld",0,"/var/run/qldap-ctrld") == -1) { + logit(1, "QmailLDAP/Ctrld: unable to read controls"); + _exit(1); + } + if (!stralloc_0(&ldap_socket)) { + logit(1, "QmailLDAP/Ctrld: out of memory"); + _exit(1); + } + + sock_path = ldap_socket.s; + sock_path[strlen(sock_path)+1] = '\0'; + } + logit(32, "done -> %s\n", sock_path); + + /* Connect to socket */ + /* ----------------- */ + addr.sun_family = PF_LOCAL; + strcpy(addr.sun_path, sock_path); + + logit(32, "opening socket: "); + sock = socket(addr.sun_family, SOCK_STREAM, 0); + if(sock == -1) { + logit(1, "Connection to socket refused\n"); + _exit(QLX_QLC_CONNFAIL); + } + logit(32, "done.\n"); + + // rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + // (char *)&tmp, sizeof(tmp) ); + + logit(32, "binding to socket: "); + r = bind(sock, (struct sockaddr *)&addr, sizeof(addr)); + if(r == -1) { + logit(1, "Can't bind to socket\n"); + _exit(QLX_QLC_BINDFAIL); + } + logit(32, "done.\n"); + + logit(32, "chmod'ing socket: "); + if(chmod(sock_path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP) < 0) { + logit(1, "can't chmod socket file\n"); + _exit(1); + } + logit(32, "done.\n"); + + logit(32, "listening: "); + r = listen(sock, 5); + if(r == -1) { + logit(1, "Can't listen on socket\n"); + _exit(1); + } + logit(32, "done.\n"); + + /* ----------------- */ + + for(;;) { + logit(32, "waiting for connections: "); + ns = accept(sock, (struct sockaddr *)&addr, &addrlen); + addrlen = read(ns, buf, BUFLEN); + buf[BUFLEN+1] = '\0'; + logit(32, "done. -> %s\n", buf); + + if(strncmp(buf, "quit", BUFLEN) == 0) { + shutdown(ns, 2); + close(ns); + + logit(32, "received quit -> we're done (for now)\n"); + unlink(sock_path); + _exit(0); + } + } + + _exit(0); +} Index: qmail-1.03/qmail-ldaplookup.c =================================================================== --- qmail-1.03.orig/qmail-ldaplookup.c +++ qmail-1.03/qmail-ldaplookup.c @@ -64,6 +64,16 @@ #define FATAL "qmail-ldaplookup: fatal: " #define WARN "qmail-ldaplookup: warning: " +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +#endif + void temp_nomem(void) { @@ -113,7 +123,7 @@ stralloc bar = {0}; int main(int argc, char **argv) { enum { unset, uid, mail, filter } mode = unset; - qldap *q, *qpw; + qldap *q; struct passwd *pw; char *passwd = 0, *value = 0; char *bindpw = 0, *binddn = 0; @@ -184,7 +194,7 @@ int main(int argc, char **argv) case 'p': if (geteuid() != 0) strerr_die2x(1, FATAL, - "only the superuser may comapre passwords"); + "only the superuser may compare passwords"); passwd = optarg; break; case 'w': @@ -201,17 +211,17 @@ int main(int argc, char **argv) if (read_controls(ctrls) != 0) strerr_die2sys(111, FATAL, "unable to read controls: "); +#ifdef USE_CONTROLDB + logit(128, "Binding to LDAP server %s as '%s':\n", ldap_server.s, ldap_login.s); +#endif + q = qldap_new(); if (q == 0) strerr_die2sys(111, FATAL, "qldap_new failed: "); - qpw = qldap_new(); - if (qpw == 0) - strerr_die2sys(111, FATAL, "qldap_new failed: "); r = qldap_open(q); if (r != OK) fail(q, "qldap_open", r); - r = qldap_open(qpw); - if (r != OK) fail(qpw, "qldap_open", r); + r = qldap_bind(q, binddn, bindpw); if (r != OK) fail(q, "qldap_bind", r); @@ -238,7 +248,7 @@ int main(int argc, char **argv) default: usage(); } - output(subfdout, "Searching ldap for: %s\nunder dn: %s\n", + output(subfdout, "Searching LDAP for:\n %s\n below dn: %s\n", f, qldap_basedn()); r = qldap_filter(q, f, attrs, qldap_basedn(), SCOPE_SUBTREE); if (r != OK) fail(q, "qldap_filter", r); @@ -497,7 +507,7 @@ int main(int argc, char **argv) LDAP_PASSWD ")", r); r = cmp_passwd(passwd, foo.s); } else { - r = qldap_rebind(qpw, dn.s, passwd); + r = qldap_rebind(q, dn.s, passwd); switch (r) { case OK: r = OK; Index: qmail-1.03/qmail-lspawn.c =================================================================== --- qmail-1.03.orig/qmail-lspawn.c +++ qmail-1.03/qmail-lspawn.c @@ -41,6 +41,9 @@ #ifdef AUTOHOMEDIRMAKE #include "dirmaker.h" #endif +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +#include "control.h" +#endif const char *aliasempty; @@ -49,6 +52,17 @@ const char *aliasempty; void forward_mail(char *, char *, char *, int , int); #endif +#ifdef USE_CONTROLDB +#include +qldap *q; + +stralloc ldap_me; +stralloc ldap_server; +stralloc ldap_password; +stralloc ldap_login; +stralloc ldap_controldn; +#endif + #ifdef AUTOHOMEDIRMAKE void check_home(const char *home, const char *maildir) { @@ -253,7 +267,9 @@ int qldap_get(stralloc *mail, unsigned i char num[FMT_ULONG]; char *f; struct passwd *pw; +#ifndef USE_CONTROLDB struct qldap *q; +#endif struct stat st; unsigned long count; unsigned long maxsize; Index: qmail-1.03/qmail-newmrh.c =================================================================== --- qmail-1.03.orig/qmail-newmrh.c +++ qmail-1.03/qmail-newmrh.c @@ -12,9 +12,38 @@ #include "auto_qmail.h" #include "cdb_make.h" #include "case.h" +#include "qldap.h" #define FATAL "qmail-newmrh: fatal: " +#ifdef USE_CONTROLDB +#include "stralloc.h" +#include +qldap *q; + +stralloc ldap_me; +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; + +void die_nomem() { + strerr_die2sys(111,FATAL,"out of memory: "); +} +#endif + void die_read() { strerr_die2sys(111,FATAL,"unable to read control/morercpthosts: "); @@ -37,8 +66,13 @@ int match; int main() { umask(033); + if (chdir(auto_qmail) == -1) strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": "); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) + strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": "); +#endif fd = open_read("control/morercpthosts"); if (fd == -1) die_read(); @@ -71,5 +105,8 @@ int main() if (rename("control/morercpthosts.tmp","control/morercpthosts.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move control/morercpthosts.tmp to control/morercpthosts.cdb"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif return 0; } Index: qmail-1.03/qmail-pw2u.c =================================================================== --- qmail-1.03.orig/qmail-pw2u.c +++ qmail-1.03/qmail-pw2u.c @@ -18,30 +18,69 @@ #include "auto_qmail.h" #include "auto_usera.h" #include "byte.h" +#include "qldap.h" + +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; + +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif void die_chdir() { substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to chdir\n"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_nomem() { substdio_putsflush(subfderr,"qmail-pw2u: fatal: out of memory\n"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_read() { substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to read input\n"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_write() { substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to write output\n"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_control() { substdio_putsflush(subfderr,"qmail-pw2u: fatal: unable to read controls\n"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_alias() @@ -50,6 +89,9 @@ void die_alias() substdio_puts(subfderr,auto_usera); substdio_puts(subfderr," user\n"); substdio_flush(subfderr); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_home(fn) char *fn; @@ -58,6 +100,9 @@ void die_home(fn) char *fn; substdio_puts(subfderr,fn); substdio_puts(subfderr,"\n"); substdio_flush(subfderr); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } void die_user(s,len) char *s; unsigned int len; @@ -66,6 +111,9 @@ void die_user(s,len) char *s; unsigned i substdio_put(subfderr,s,len); substdio_puts(subfderr," user for subuser\n"); substdio_flush(subfderr); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(111); } @@ -253,8 +301,9 @@ char **argv; } if (chdir(auto_qmail) == -1) die_chdir(); - - /* no need for control_init() */ +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die_chdir(); +#endif okincl = control_readfile(&incl,"users/include",0); if (okincl == -1) die_control(); @@ -310,5 +359,8 @@ char **argv; if (substdio_puts(subfdout,".\n") == -1) die_write(); if (substdio_flush(subfdout) == -1) die_write(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif return 0; } Index: qmail-1.03/qmail-qmqpc.c =================================================================== --- qmail-1.03.orig/qmail-qmqpc.c +++ qmail-1.03/qmail-qmqpc.c @@ -22,19 +22,58 @@ #include #endif +#include "qldap.h" +#ifdef USE_CONTROLDB +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +stralloc qmqp_port = {0}; +unsigned long port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#else #ifndef PORT_QMQP /* this is for testing purposes */ #define PORT_QMQP 628 #endif +#endif void die_success(void) { _exit(0); } +#ifdef USE_CONTROLDB +void die_perm() { qldap_close(q); _exit(31); } +void nomem() { qldap_close(q); _exit(51); } +#else void die_perm(void) { _exit(31); } void nomem(void) { _exit(51); } +#endif void die_read(void) { if (errno == error_nomem) nomem(); _exit(54); } +#ifdef USE_CONTROLDB +void die_control() { qldap_close(q); _exit(55); } +#else void die_control(void) { _exit(55); } +#endif void die_socket(void) { _exit(56); } +#ifdef USE_CONTROLDB +void die_home() { qldap_close(q); _exit(61); } +void die_temp() { qldap_close(q); _exit(71); } +#else void die_home(void) { _exit(61); } void die_temp(void) { _exit(71); } +#endif void die_conn(void) { _exit(74); } void die_format(void) { _exit(91); } @@ -184,7 +223,11 @@ char *server; qmqpfd = socket(AF_INET,SOCK_STREAM,0); if (qmqpfd == -1) die_socket(); +#ifdef USE_CONTROLDB + if (timeoutconn(qmqpfd,&ip,&outip,port,timeoutconnect) != 0) { +#else if (timeoutconn(qmqpfd,&ip,&outip,PORT_QMQP,timeoutconnect) != 0) { +#endif lasterror = 73; if (errno == error_timeout) lasterror = 72; close(qmqpfd); @@ -233,7 +276,16 @@ char **argv; sig_pipeignore(); if (chdir(auto_qmail) == -1) die_home(); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die_home(); + + if (control_rldef(&qmqp_port,"control/port_qmqp",0,"628") == -1) + die_control(); + if (!stralloc_0(&qmqp_port)) nomem(); + port = atoi(qmqp_port.s); +#else if (control_init() == -1) die_control(); +#endif if ( argv[1] ) { char temp[IPFMT]; if (!stralloc_copys(&servers,argv[1])) nomem(); @@ -257,6 +309,9 @@ char **argv; die_control(); if (!stralloc_0(&outgoingip)) nomem(); if (!ip_scan(outgoingip.s,&outip)) die_control(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif getmess(); Index: qmail-1.03/qmail-qmtpd.c =================================================================== --- qmail-1.03.orig/qmail-qmtpd.c +++ qmail-1.03/qmail-qmtpd.c @@ -13,9 +13,38 @@ #include "control.h" #include "received.h" #include "scan.h" +#include "qldap.h" +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_me; +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif + +#ifdef USE_CONTROLDB +void badproto() { qldap_close(q); _exit(100); } +void resources() { qldap_close(q); _exit(111); } +#else void badproto() { _exit(100); } void resources() { _exit(111); } +#endif int safewrite(int fd, void *buf, int len) { @@ -95,13 +124,19 @@ int main() alarm(3600); if (chdir(auto_qmail) == -1) resources(); - +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) resources(); +#else if (control_init() == -1) resources(); +#endif if (rcpthosts_init() == -1) resources(); relayclient = env_get("RELAYCLIENT"); relayclientlen = relayclient ? str_len(relayclient) : 0; if (control_readulong(&databytes,"control/databytes") == -1) resources(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif x = env_get("DATABYTES"); if (x) scan_ulong(x,&databytes); if (!(databytes + 1)) --databytes; Index: qmail-1.03/qmail-queue.c =================================================================== --- qmail-1.03.orig/qmail-queue.c +++ qmail-1.03/qmail-queue.c @@ -31,7 +31,32 @@ int bbon = 0; stralloc bbs = {0}; stralloc bbaddr = {0}; struct constmap mapbb; +#endif + +#include "qldap.h" + +#ifdef USE_CONTROLDB +#include "stralloc.h" +#include +qldap *q; + +stralloc ldap_me; +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; #endif char inbuf[2048]; @@ -87,7 +112,7 @@ char *s; unsigned int i; unsigned int len; len = 0; - i = fmt_str(s,"Received: (qmail "); len += i; if (s) s += i; + i = fmt_str(s,"Received: (qmail-ldap/ctrl "); len += i; if (s) s += i; i = fmt_ulong(s,mypid); len += i; if (s) s += i; i = fmt_str(s," invoked "); len += i; if (s) s += i; if (uid == auto_uida) @@ -183,13 +208,20 @@ int main() if (chdir(auto_qmail) == -1) die(61); #ifdef BIGBROTHER +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) die(61); +#else if (control_init() == -1) die(55); +#endif switch (control_readfile(&bbs,"control/bigbrother",0)) { case -1: die(55); case 0: bbon = 0; if (!constmap_init(&mapbb,"",0,1)) die(51); break; case 1: bbon = 1; if (!constmap_init(&mapbb,bbs.s,bbs.len,1)) die(51); break; } +#ifdef USE_CONTROLDB + qldap_close(q); +#endif #endif if (chdir("queue") == -1) die(62); Index: qmail-1.03/qmail-quotawarn.c =================================================================== --- qmail-1.03.orig/qmail-quotawarn.c +++ qmail-1.03/qmail-quotawarn.c @@ -73,6 +73,31 @@ stralloc header = {0}; stralloc qwline = {0}; stralloc temp = {0}; +#include "qldap.h" + +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_me; +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif + #define FATAL "qmail-quotawarn: fatal: " #define WARN "qmail-quotawarn: warn: " @@ -108,6 +133,7 @@ readcontrol(void) { int fddir; +#ifndef USE_CONTROLDB fddir = open_read("."); if (fddir == -1) strerr_die2sys(111, FATAL, "Unable to open cwd: "); @@ -119,6 +145,7 @@ readcontrol(void) strerr_die2sys(111, FATAL, "Unable to read controls: "); if (control_readline(&me, "control/me") != 1) strerr_die2sys(111, FATAL, "Unable to read control/me: "); +#endif if (control_readrawfile(&warning, "control/quotawarning") == -1) strerr_die2sys(111, FATAL, "Unable to read control/quotawarning: "); @@ -143,7 +170,14 @@ main(int argc, char **argv) fn = argv[1]; +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) + { strerr_die2x(111, FATAL, "Can't read controls."); _exit(111); } +#endif readcontrol(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif if (!env_init()) temp_nomem(); if (!(s = env_get("USER"))) Index: qmail-1.03/qmail-remote.c =================================================================== --- qmail-1.03.orig/qmail-remote.c +++ qmail-1.03/qmail-remote.c @@ -51,6 +51,30 @@ SSL *ssl = 0; #define HUGESMTPTEXT 5000 +#include "qldap.h" + +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif + #ifndef PORT_SMTP /* this is for testing purposes, so you can overwrite it */ #define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */ #endif @@ -853,7 +877,9 @@ int flagcname; void getcontrols(void) { +#ifndef USE_CONTROLDB if (control_init() == -1) temp_control(); +#endif if (control_rldef(&cookie,"control/smtpclustercookie",0,"") == -1) temp_control(); if (cookie.len > 32) cookie.len = 32; @@ -900,8 +926,13 @@ int main(int argc, char **argv) sig_pipeignore(); if (argc < 4) perm_usage(); if (chdir(auto_qmail) == -1) temp_chdir(); +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) temp_chdir(); +#endif getcontrols(); - +#ifdef USE_CONTROLDB + qldap_close(q); +#endif if (!stralloc_copys(&host,argv[1])) temp_nomem(); if (!stralloc_copys(&auth_login, "")) temp_nomem(); Index: qmail-1.03/qmail-reply.c =================================================================== --- qmail-1.03.orig/qmail-reply.c +++ qmail-1.03/qmail-reply.c @@ -64,6 +64,20 @@ #define FATAL "qmail-reply: fatal: " #define WARN "qmail-reply: warn: " +#ifdef USE_CONTROLDB +#include "stralloc.h" +#include +#include "qldap.h" +qldap *q; + +stralloc ldap_me; +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; +#endif + void temp_nomem(void) { Index: qmail-1.03/qmail-secretary.c =================================================================== --- qmail-1.03.orig/qmail-secretary.c +++ qmail-1.03/qmail-secretary.c @@ -70,6 +70,21 @@ #define FATAL "qmail-secretary: fatal: " #define WARN "qmail-secretary: warn: " +#ifdef USE_CONTROLDB +#include "qldap.h" +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif +#endif + const char *confirmmess = "Hi,\n\n\ I'm mailgroup secretary, an automated mail-handling program.\n\ I received a message from you addressed to %LIST%\n\ Index: qmail-1.03/qmail-send.c =================================================================== --- qmail-1.03.orig/qmail-send.c +++ qmail-1.03/qmail-send.c @@ -61,6 +61,38 @@ stralloc doublebouncehost = {0}; stralloc custombouncetext = {0}; +#include "qldap.h" + +#ifdef USE_CONTROLDB +#include +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; + +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#ifdef QLDAP_CLUSTER +#include "qldap-cluster.h" +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, +#ifdef QLDAP_CLUSTER + cluster_init, +#endif + 0 +}; +#endif + char strnum2[FMT_ULONG]; char strnum3[FMT_ULONG]; @@ -1734,7 +1766,9 @@ int getcontrols() { struct stat st; +#ifndef USE_CONTROLDB if (control_init() == -1) return 0; +#endif if (control_readint(&lifetime,"control/queuelifetime") == -1) return 0; if (control_readint(&concurrency[0],"control/concurrencylocal") == -1) return 0; if (control_readint(&concurrency[1],"control/concurrencyremote") == -1) return 0; @@ -1856,8 +1890,16 @@ int main() struct timeval tv; int c; +#ifdef DEBUG + log_init(0, -1, 1); +#endif + if (chdir(auto_qmail) == -1) { log1("alert: cannot start: unable to switch to home directory\n"); _exit(111); } +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) + { log1("alert: qmail-todo: cannot start: unable to read controls\n"); _exit(111); } +#endif if (!getcontrols()) { log1("alert: cannot start: unable to read controls\n"); _exit(111); } if (chdir("queue") == -1) @@ -1956,5 +1998,8 @@ int main() } pqfinish(); log1("status: exiting\n"); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif return 0; } Index: qmail-1.03/qmail-showctl.c =================================================================== --- qmail-1.03.orig/qmail-showctl.c +++ qmail-1.03/qmail-showctl.c @@ -18,10 +18,37 @@ #include "auto_split.h" #include "byte.h" +#ifdef USE_CONTROLDB +#include +#ifdef DEBUG +#include "output.h" +#endif +#include "qldap.h" +qldap *q; + +extern stralloc ldap_me; +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif stralloc me = {0}; int meok; +#ifndef USE_CONTROLDB stralloc ldapserver = {0}; +#endif int ldapok; stralloc line = {0}; @@ -109,6 +136,11 @@ int flagme; char *def; char *pre; { +#ifdef USE_CONTROLDB + // We have to zero this variable, it's global! + stralloc_copys(&line,""); +#endif + substdio_puts(subfdout,"\n"); substdio_puts(subfdout,fn); substdio_puts(subfdout,": "); @@ -143,6 +175,10 @@ char *post; { unsigned int i; unsigned int j; +#ifdef USE_CONTROLDB + // We have to zero this variable, it's global! + stralloc_copys(&line,""); +#endif substdio_puts(subfdout,"\n"); substdio_puts(subfdout,fn); @@ -248,6 +284,13 @@ int main() substdio_flush(subfdout); _exit(111); } +#ifdef USE_CONTROLDB +#ifdef DEBUG + // Log to STDERR + log_init(STDERR, -1, 0); +#endif + if (read_controls(ctrls) != 0) _exit(111); +#else ldapok = control_readfile(&ldapserver,"ldapserver",0); byte_repl(ldapserver.s, ldapserver.len, '\0', ' '); if (ldapok == -1) { @@ -255,12 +298,14 @@ int main() substdio_flush(subfdout); _exit(111); } + substdio_puts(subfdout,"me: My name is "); substdio_put(subfdout, me.s, me.len); + substdio_puts(subfdout,"\nldapserver: My ldap server is "); substdio_put(subfdout, ldapserver.s, ldapserver.len); substdio_puts(subfdout,"\n\n"); - +#endif do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM."); do_lst("badmailfrom-unknown","Any MAIL FROM from hosts without PTR is allowed.","", @@ -333,10 +378,19 @@ int main() substdio_puts(subfdout,"\n\n\nNow the qmail-ldap specific files:\n"); - do_str("ldapbasedn",0,"NULL","LDAP basedn: "); do_lst("ldapserver","undefined! Uh-oh","",""); +#ifdef USE_CONTROLDB + do_int("port_ldap","389","LDAP Port: ",""); +#endif do_str("ldaplogin",0,"NULL","LDAP login: "); +#if defined(USE_CONTROLDB) && defined(DEBUG) + /* Only output this if we have DEBUG on... */ do_str("ldappassword",0,"NULL","LDAP password: "); +#endif + do_str("ldapbasedn",0,"NULL","LDAP basedn: "); +#ifdef USE_CONTROLDB + do_str("ldapcontroldn","undefined! Uh-oh","",""); +#endif do_int("ldaptimeout","30","LDAP server timeout is "," seconds"); do_str("ldapuid",0,"not defined","Default UID is "); do_str("ldapgid",0,"not defined","Default GID is "); @@ -350,6 +404,11 @@ int main() do_int("ldapcluster","0","Clustering is "," (1 = on, 0 = off)"); do_lst("ldapclusterhosts","Messages for me are not redirected.", "Messages for "," are not redirected."); +#ifdef USE_CONTROLDB +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) + do_str("ldapsecurebind",0,"not secure","LDAP Secure options: "); +#endif +#endif substdio_puts(subfdout,"\n"); @@ -382,6 +441,9 @@ int main() if (str_equal(d->d_name,"ldapbasedn")) continue; if (str_equal(d->d_name,"ldapcluster")) continue; if (str_equal(d->d_name,"ldapclusterhosts")) continue; +#ifdef USE_CONTROLDB + if (str_equal(d->d_name,"ldapcontroldn")) continue; +#endif if (str_equal(d->d_name,"ldapdefaultdotmode")) continue; if (str_equal(d->d_name,"ldapgid")) continue; if (str_equal(d->d_name,"ldaplocaldelivery")) continue; @@ -389,7 +451,13 @@ int main() if (str_equal(d->d_name,"ldapmessagestore")) continue; if (str_equal(d->d_name,"ldapobjectclass")) continue; if (str_equal(d->d_name,"ldappassword")) continue; +#ifdef USE_CONTROLDB + if (str_equal(d->d_name,"port_ldap")) continue; +#endif if (str_equal(d->d_name,"ldaprebind")) continue; +#ifdef USE_CONTROLDB + if (str_equal(d->d_name,"ldapsecurebind")) continue; +#endif if (str_equal(d->d_name,"ldapserver")) continue; if (str_equal(d->d_name,"ldaptimeout")) continue; if (str_equal(d->d_name,"ldapuid")) continue; @@ -409,6 +477,9 @@ int main() if (str_equal(d->d_name,"percenthack")) continue; if (str_equal(d->d_name,"plusdomain")) continue; if (str_equal(d->d_name,"qmqpcip")) continue; +#ifdef USE_CONTROLDB + if (str_equal(d->d_name,"port_qmqp")) continue; +#endif if (str_equal(d->d_name,"qmqpservers")) continue; if (str_equal(d->d_name,"queuelifetime")) continue; if (str_equal(d->d_name,"quotawarning")) continue; @@ -416,6 +487,9 @@ int main() if (str_equal(d->d_name,"rcpthosts")) continue; if (str_equal(d->d_name,"relaymailfrom")) continue; if (str_equal(d->d_name,"smtpgreeting")) continue; +#ifdef USE_CONTROLDB + if (str_equal(d->d_name,"port_smtp")) continue; +#endif if (str_equal(d->d_name,"smtproutes")) continue; if (str_equal(d->d_name,"timeoutconnect")) continue; if (str_equal(d->d_name,"timeoutremote")) continue; Index: qmail-1.03/qmail-smtpd.c =================================================================== --- qmail-1.03.orig/qmail-smtpd.c +++ qmail-1.03/qmail-smtpd.c @@ -48,6 +48,29 @@ SSL *ssl = NULL; unsigned long databytes = 0; int timeout = 1200; +#include "qldap.h" + +#ifdef USE_CONTROLDB +qldap *q; + +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif + #ifdef TLS_SMTPD int flagtimedout = 0; void sigalrm() @@ -159,9 +182,15 @@ void die_write(void) { logline(1,"write void die_alarm(void) { out("451 timeout (#4.4.2)\r\n"); logline(1,"connection timed out, closing connection"); flush(); cleanup(); _exit(1); } void die_nomem(void) { out("421 out of memory (#4.3.0)\r\n"); logline(1,"out of memory, closing connection"); flush(); cleanup(); _exit(1); } void die_control(void) { out("421 unable to read controls (#4.3.0)\r\n"); logline(1,"unable to read controls, closing connection"); flush(); _exit(1); } +#ifdef USE_CONTROLDB +void die_ipme(void) { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); logline(1,"unable to figure out my IP address, closing connection"); flush(); qldap_close(q); _exit(1); } +void straynewline(void) { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); logline(1,"stray new line detected, closing connection"); flush(); qldap_close(q); _exit(1); } +void oversizedline(void) { out("500 Text line too long."); logline(1,"Oversized line in data part, closing connection"); flush(); qldap_close(q); _exit(1); } +#else void die_ipme(void) { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); logline(1,"unable to figure out my IP address, closing connection"); flush(); _exit(1); } void straynewline(void) { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); logline(1,"stray new line detected, closing connection"); flush(); _exit(1); } void oversizedline(void) { out("500 Text line too long."); logline(1,"Oversized line in data part, closing connection"); flush(); _exit(1); } +#endif void err_qqt(void) { out("451 qqt failure (#4.3.0)\r\n"); } void err_dns(void) { out("421 DNS temporary failure at return MX check, try again later (#4.3.0)\r\n"); } void err_soft(char *s) { out("451 "); out(s); out("\r\n"); logline2(1,"temporary verify error: ", s); } @@ -308,7 +337,12 @@ void setup(void) l = env_get("LOGLEVEL"); if (l) { scan_ulong(l,&u); loglevel = u > 4 ? 4 : u; } +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) + die_control(); +#else if (control_init() == -1) die_control(); +#endif if (control_readline(&me,"control/me") != 1) die_control(); @@ -1687,6 +1721,9 @@ void smtp_tls(char *arg) void cleanup(void) { ldaplookupdone(); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif } void err_503or421(char *arg) Index: qmail-1.03/qmail-start.c =================================================================== --- qmail-1.03.orig/qmail-start.c +++ qmail-1.03/qmail-start.c @@ -14,6 +14,9 @@ const char *(qrargs[]) = { "qmail-rspawn #ifdef EXTERNAL_TODO const char *(qtargs[]) = { "qmail-todo", 0}; #endif +#ifdef USE_CTRLD +const char *(qdargs[]) = { "qmail-ldapctrld", 0 }; +#endif void die() { _exit(111); } @@ -66,6 +69,23 @@ char **argv; if (fd_copy(8,0) == -1) die(); #endif +#ifdef USE_CTRLD + /* We don't mind if the QmailLDAP/Ctrld can't be + * started for some reason - hence no 'case -1: die()' + * in the switch below. */ + switch(fork()) { + case 0: + if (prot_gid(auto_gidq) == -1) die(); + if (prot_uid(auto_uidd) == -1) die(); + if (fd_copy(0,pi1[0]) == -1) die(); + if (fd_copy(1,pi2[1]) == -1) die(); + close23456(); + closepipes(); + execvp(*qdargs,(char **)qdargs); + die(); + } +#endif + if (argv[1]) { qlargs[1] = argv[1]; ++argv; Index: qmail-1.03/qmail-todo.c =================================================================== --- qmail-1.03.orig/qmail-todo.c +++ qmail-1.03/qmail-todo.c @@ -60,6 +60,28 @@ #include "stralloc.h" #include "substdio.h" #include "trigger.h" +#include "qldap.h" + +#ifdef USE_CONTROLDB +qldap *q; + +stralloc ldap_server; +stralloc ldap_login; +stralloc ldap_password; +stralloc ldap_controldn; +stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif + +#include "read-ctrl.h" +ctrlfunc ctrls[] = { + qldap_ctrl_trylogin, + qldap_ctrl_generic, + 0 +}; +#endif /* critical timing feature #1: if not triggered, do not busy-loop */ /* critical timing feature #2: if triggered, respond within fixed time */ @@ -652,7 +674,9 @@ int getcontrols(void) { struct stat st; +#ifndef USE_CONTROLDB if (control_init() == -1) return 0; +#endif if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1) return 0; if (stat("control/locals.cdb", &st) == 0) { @@ -748,6 +772,10 @@ int main() if (chdir(auto_qmail) == -1) { log1("alert: qmail-todo: cannot start: unable to switch to home directory\n"); _exit(111); } +#ifdef USE_CONTROLDB + if (read_controls(ctrls) == -1) + { log1("alert: qmail-todo: cannot start: unable to read controls\n"); _exit(111); } +#endif if (!getcontrols()) { log1("alert: qmail-todo: cannot start: unable to read controls\n"); _exit(111); } if (chdir("queue") == -1) @@ -763,9 +791,17 @@ int main() do { r = read(fdin, &c, 1); if ((r == -1) && (errno != error_intr)) +#ifdef USE_CONTROLDB + { qldap_close(q); _exit(100); } +#else _exit(100); /* read failed probably qmail-send died */ +#endif if (r == 0) /* Uh-oh, qmail-send died. */ +#ifdef USE_CONTROLDB + { qldap_close(q); _exit(100); } +#else _exit(100); +#endif } while (r != 1); /* we assume it is a 'S' */ for (;;) @@ -775,11 +811,18 @@ int main() if (flagreadasap) { flagreadasap = 0; reread(); } if (!flagsendalive) { /* qmail-send finaly exited, so do the same. */ +#ifdef USE_CONTROLDB + if (flagstopasap) { qldap_close(q); _exit(0); } +#else if (flagstopasap) _exit(0); +#endif /* * qmail-send died. * We can not log and we can not work therefor _exit(1). */ +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(1); } @@ -809,6 +852,10 @@ int main() } } /* NOTREACHED */ +#ifdef USE_CONTROLDB + /* still... Don't know exactly where to put this... TODO! */ + qldap_close(q); +#endif return 1; } Index: qmail-1.03/qmail-verify.c =================================================================== --- qmail-1.03.orig/qmail-verify.c +++ qmail-1.03/qmail-verify.c @@ -57,6 +57,18 @@ struct qldap *q; +#ifdef USE_CONTROLDB +extern stralloc ldap_server; +extern stralloc ldap_login; +extern stralloc ldap_password; +extern stralloc ldap_controldn; +extern stralloc ldap_port; + +#if defined(SECUREBIND_SASL) || defined(SECUREBIND_SSL) || defined(SECUREBIND_TLS) || defined(SECUREBIND_ALL) +extern stralloc ldap_securebind; +#endif +#endif + void cleanup(void); void die_read(void) Index: qmail-1.03/strerr_die.c =================================================================== --- qmail-1.03.orig/strerr_die.c +++ qmail-1.03/strerr_die.c @@ -3,6 +3,10 @@ #include "exit.h" #include "strerr.h" +#ifdef USE_CONTROLDB +qldap *q; +#endif + void strerr_warn(x1,x2,x3,x4,x5,x6,se) const char *x1; const char *x2; const char *x3; const char *x4; const char *x5; const char *x6; @@ -35,5 +39,8 @@ const char *x4; const char *x5; const ch struct strerr *se; { strerr_warn(x1,x2,x3,x4,x5,x6,se); +#ifdef USE_CONTROLDB + qldap_close(q); +#endif _exit(e); }