Bruno,
I seem to be having bad luck with my patch files lately. This one should be a
little better . . .
--Ed
On Thursday 14 July 2005 08:54, Bruno Negrao wrote:
> Ed,
>
> The patch file you sent to me was 0 bytes long. Can you resend it again?
>
> Thank you,
> bnegrao
> ----- Original Message -----
> From: "Ed Cates" <[EMAIL PROTECTED]>
> To: "Bruno Negrao" <[EMAIL PROTECTED]>; <[email protected]>
> Sent: Sunday, July 10, 2005 12:55 AM
> Subject: Re: qmail-ldap-virtual applyied with fuzz
>
> > On Saturday 09 July 2005 15:04, you wrote:
> >> Hi Kristof,
> >>
> >> I tried to apply your patch upon qmail-ldap 20050401a and it reported
> >> the
> >> following messages. Can you say if this is bad?
> >>
> >> [EMAIL PROTECTED] qmail-1.03]# patch <
> >> /root/pacotes/QMAIL_WORLD/qmail-ldap-virtual.20040701.patch
> >> patching file Makefile
> >> Hunk #6 succeeded at 2185 with fuzz 1 (offset 2 lines).
> >> patching file VIRTUAL.readme
> >> patching file checkpassword.c
> >> patching file qldap.c
> >> Hunk #3 succeeded at 186 (offset 2 lines).
> >> Hunk #5 succeeded at 274 (offset 2 lines).
> >> patching file qldap.h
> >> patching file qmail-ldap.h
> >> Hunk #1 succeeded at 187 (offset 1 line).
> >>
> >> And I see your patch is for version 20040701. Would you update it?
> >>
> >> Thank you very much,
> >> bnegrao
> >
> > Bruno,
> >
> > As long as the patch doesn't "FAIL" anywhere you should be good to go.
> >
> > I'm mulling over a good way to include/exclude Kristof's patch in a
> > qmail-ldap
> > ebuild I'm working on for Gentoo Linux (I would say the current ebuild
> > sucks,
> > but only if it actually worked), and have updated it for the latest
> > qmail-ldap patch. Let me know how this works for you (attached).
> >
> > --Ed
--- Makefile.old 2005-07-13 15:53:33.955241120 -0500
+++ Makefile 2005-07-13 15:53:47.564172248 -0500
@@ -52,6 +52,11 @@
#OPENSSLBIN=/usr/local/bin/openssl
#OPENSSLBIN=openssl
+# Virtual domain support: see VIRTUAL.readme
+# use -DIP_VIRTUAL to enable IP-based virtual domain support
+# use -DNAMED_VIRTUAL to enable username-based virtual domain support
+#VIRTUAL=-DIP_VIRTUAL -DNAMED_VIRTUAL
+
# to make the Netscape download progress bar work with qmail-pop3d
# uncomment the next line (allready done)
MNW=-DMAKE_NETSCAPE_WORK
@@ -140,7 +145,7 @@
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
- ./compile $(LDAPFLAGS) $(DEBUG) $(HDIRMAKE) $(MDIRMAKE) auth_mod.c
+ ./compile $(LDAPFLAGS) $(DEBUG) $(HDIRMAKE) $(MDIRMAKE) $(VIRTUAL) auth_mod.c
auth_pop: \
load auth_pop.o auth_mod.o checkpassword.o passwd.o digest_md4.o \
@@ -457,7 +462,7 @@
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) $(DEBUG) $(VIRTUAL) checkpassword.c
chkshsgr: \
load chkshsgr.o
@@ -1404,8 +1409,9 @@
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
+fmt.h qldap-debug.h qldap-errno.h qmail-ldap.h scan.h str.h stralloc.h \
+constmap.h
+ ./compile $(LDAPFLAGS) $(LDAPINCLUDES) $(DEBUG) $(VIRTUAL) qldap.c
qldap-cluster.o: \
compile qldap-cluster.c qldap-cluster.h constmap.h control.h qldap-debug.h \
@@ -1515,10 +1521,11 @@
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 \
-substdio.a error.a fs.a str.a coe.o auto_qmail.o
+substdio.a error.a fs.a str.a coe.o auto_qmail.o constmap.o case_diffb.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 \
alloc.a fs.a strerr.a substdio.a error.a str.a coe.o auto_qmail.o \
+ constmap.o case_diffb.o \
$(LDAPLIBS)
qmail-group.o: \
@@ -2178,10 +2185,10 @@
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 str.a timeoutread.o \
-auto_qmail.o
+auto_qmail.o constmap.o case_diffb.o
./load qmail-verify 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 \
- str.a timeoutread.o auto_qmail.o $(LDAPLIBS)
+ str.a timeoutread.o auto_qmail.o constmap.o case_diffb.o $(LDAPLIBS)
qmail-verify.o: \
compile qmail-verify.c error.h getln.h output.h qldap.h qldap-debug.h \
--- VIRTUAL.readme.old 2005-07-13 15:53:33.959240512 -0500
+++ VIRTUAL.readme 2005-07-13 15:53:47.568171640 -0500
@@ -0,0 +1,68 @@
+Virtual domain support for qmail-ldap
+=====================================
+
+Author: Kristof Bajnok ([EMAIL PROTECTED])
+9 January 2004
+
+--------
+
+The term "virtual domain support" means that you can define seperate ldap
+brunches (base DN's) for your different domains used in authentication in
+order to have them being administered independently.
+
+There are basically two types of virtual domain support
+ - IP based virtual domains
+ - username based virtual domains
+
+1. IP based virtual domains
+---------------------------
+You should use IP based virtual domains, if you have to integrate several
+different user databases, coming from non-virtual environment. In this case,
+you can rarely guarantee that usernames are unique.
+If you don't want your users to change their usernames from 'user' to
+'[EMAIL PROTECTED]' form, you should use different IP addresses for each
+virtual domain, so that you can define a base DN for each address.
+The whole concept of this implementation assumes that you are using a tcp
+wrapper in front of your [smtp|pop3|imap] servers, which sets the TCPLOCALIP
+environment variable, containing the IP address (of the server) to which the
+client is bound. Tcpserver (included in ucspi-tcp package) is OK.
+When a connection comes in, the base DN being used for authenticating the
+user is selected according to TCPLOCALIP.
+You can specify 'local ip' -> 'ldap' basedn mappings in control/ipvirtualbasedn.
+The form of this file is as follows: ip_address:ldap_basedn
+You can specify more than one mapping, the file is multiline. Only one mapping
+per a single IP address is allowed.
+Unless a mapping is defined for TCPLOCALIP, control/ldapbasedn will be used.
+
+2. Username based virtual domains
+---------------------------------
+If your users have usernames that have a "virtual domain part" (something
+that can identify the virtual domain, ie: [EMAIL PROTECTED]), you can assign
+different ldap basedn's for each domain.
+By default the separator between user and domain parts is '@'. You can change
+it by editing qldap.h (VIRTUAL_SEPARATOR), but then you should take a look at
+check.c!
+You can define 'domain' -> 'ldap basedn' mappings in control/namedvirtualbasedn
+The form of this file is as follows: domain:ldap_basedn
+You can specify more than one mapping, the file is multiline. Only one mapping
+per domain is allowed.
+In the LDAP database the uid field of the users in the virtual domain brunch
+should contain only the "username" part, and not "@domain". (Users still have
+to use [EMAIL PROTECTED] form in their mail client.)
+If the domain is not found in control/namedvirtualbasedn, control/ldapbasedn
+will be used and authentication will go as usual (searching for
[EMAIL PROTECTED]).
+
+Mixing IP-based and username based virtual domains
+--------------------------------------------------
+The procedure is as follows:
+ - if the username has a virtual domain part, then the basedn will be set
+ according to control/namedvirtualbasedn
+ - control/ipvirtualbasedn is only checked if username doesn't contain
+ virtual domain
+ - if neither approach succeeds, ldap search for authentication will have a
+ basedn defined in control/ldapbasedn (and username unchanged).
+
+
+Please send your questions and comments to [EMAIL PROTECTED]
+
--- checkpassword.c.old 2005-07-13 15:53:33.963239904 -0500
+++ checkpassword.c 2005-07-13 15:53:47.570171336 -0500
@@ -128,9 +128,18 @@
attrs[10] = 0;
}
+#ifdef NAMED_VIRTUAL
+ r = virtual_login(login); /* sets login & (global) virtual_basedn */
+ if (r < 0) goto fail;
+#endif
filter = filter_uid(login->s);
if (filter == 0) { r = ERRNO; goto fail; }
+#ifdef IP_VIRTUAL
+ r = virtual_ip(env_get("TCPLOCALIP")); /* sets (global) virtual_basedn*/
+ if (r < 0) goto fail;
+#endif
+
r = qldap_lookup(q, filter, attrs);
if (r != OK) goto fail;
--- qldap.c.old 2005-07-13 15:53:33.967239296 -0500
+++ qldap.c 2005-07-13 15:53:47.577170272 -0500
@@ -49,6 +49,7 @@
#include "scan.h"
#include "str.h"
#include "stralloc.h"
+#include "constmap.h"
#include "qldap.h"
@@ -70,6 +71,17 @@
stralloc ldap_server = {0};
stralloc basedn = {0};
+#ifdef VIRTUAL_DN
+stralloc virtual_basedn = {0};
+#endif
+#ifdef IP_VIRTUAL
+struct constmap map_ip_dn;
+stralloc vdn_ip_file = {0};
+#endif
+#ifdef NAMED_VIRTUAL
+struct constmap map_domain_dn;
+stralloc vdn_domain_file = {0};
+#endif
stralloc objectclass = {0};
stralloc ldap_login = {0};
stralloc ldap_password = {0};
@@ -174,7 +186,27 @@
if (control_readint(&rebind, "control/ldaprebind") == -1) return -1;
logit(64, "init_ldap: control/ldaprebind: %i\n", rebind);
-
+
+#ifdef IP_VIRTUAL
+ /* control/ipvirtualbasedn */
+ if (control_readfile(&vdn_ip_file, "control/ipvirtualbasedn", 0) == -1)
+ return -1;
+ if (!constmap_init(&map_ip_dn, vdn_ip_file.s, vdn_ip_file.len, 1))
+ /* it doesn't hurt when vdn_ip_file is empty (no file) */
+ return -1;
+ /* Logging? How to log a constmap? */
+#endif
+#ifdef NAMED_VIRTUAL
+ /* control/namedvirtualbasedn */
+ if (control_readfile(&vdn_domain_file, "control/namedvirtualbasedn",0)
+ == -1)
+ return -1;
+ if (!constmap_init(&map_domain_dn,
+ vdn_domain_file.s,
+ vdn_domain_file.len, 1))
+ return -1;
+ /* Logging? How to log a constmap? */
+#endif
/* defaults */
if (control_readint(&default_uid, "control/ldapuid") == -1)
@@ -223,7 +255,12 @@
char *
qldap_basedn(void)
{
- return basedn.s;
+#ifdef VIRTUAL_DN
+ if(virtual_basedn.s && *(virtual_basedn.s))
+ return virtual_basedn.s;
+ else
+#endif
+ return basedn.s;
}
qldap *
@@ -237,6 +274,114 @@
return q;
}
+#ifdef NAMED_VIRTUAL
+int
+virtual_login(stralloc* login)
+/* Return value: -1 on error
+ * 0 if login -> virtual_basedn mapping not found
+ * 1 if login -> virtual_basedn mapping found */
+{
+ stralloc domain = {0};
+ unsigned int sep_idx;
+ const char* vbdn;
+ /* splitting to user and domain part */
+ if((sep_idx = str_rchr(login->s, VIRTUAL_SEPARATOR)) &&
+ (login->s[sep_idx] != '\0') && (login->s[sep_idx+1] != '\0'))
+ {
+ /* setting domain */
+ if(!stralloc_copyb(&domain,
+ (char*)(login->s + sep_idx + 1),
+ login->len - sep_idx - 1))
+ return -1;
+ vbdn = constmap(&map_domain_dn,domain.s,domain.len-1);
+ if(vbdn && *vbdn)
+ {
+ /* setting virtual_basedn */
+ if(!stralloc_copys(&virtual_basedn,vbdn) ||
+ !stralloc_0(&virtual_basedn))
+ {
+ /* clearing up */
+ constmap_free(&map_domain_dn);
+ stralloc_copys(&virtual_basedn, "");
+ return -1;
+ }
+ logit(64,
+ "init_ldap: control/namedvirtualbasedn: %s for login %s\n",
+ vbdn, login->s);
+ /* truncate login */
+ login->s[sep_idx] = '\0';
+ login->len = sep_idx+1;
+ constmap_free(&map_domain_dn);
+ return 1;
+ }
+ else
+ {
+ logit(64,
+ "init_ldap: control/namedvirtualbasedn: no basedn for %s\n",
+ login->s);
+ return 0;
+ }
+ }
+ else
+ {
+ /* no virtual login, so leave it untouched */
+ return 0;
+ }
+}
+#endif
+#ifdef IP_VIRTUAL
+int
+virtual_ip(const char* local_ip)
+/* Return value: -1 on error
+ * 0 if local_ip not found
+ * 1 if local_ip -> virtual_basedn mapping found */
+{
+ const char* vbdn;
+ unsigned int ip_size;
+
+ if(!local_ip)
+ return 0; /* no local IP */
+ /* Maybe constmap_free here ?! */
+ if(virtual_basedn.len > 1)
+ return 0; /* virtual domain was extracted from login name */
+
+ ip_size = str_len(local_ip);
+ if(ip_size > 128)
+ ip_size = 128; /* env contains fake data (not even IPv6!)
+ * Maybe we should terminate here */
+
+ /* searching for local ip */
+ vbdn = constmap(&map_ip_dn, local_ip, ip_size);
+ if(vbdn && *vbdn)
+ {
+ /* setting virtual_basedn */
+ if(!stralloc_copys(&virtual_basedn,vbdn) ||
+ !stralloc_0(&virtual_basedn))
+ {
+ /* Clearing up on error */
+ constmap_free(&map_ip_dn);
+ stralloc_copys(&virtual_basedn,"");
+ return -1;
+ }
+ logit(64,
+ "init_ldap: control/ipvirtualbasedn: %s for local ip %s\n",
+ vbdn, local_ip);
+ constmap_free(&map_ip_dn);
+ return 1;
+
+ }
+ else
+ {
+ logit(64,
+ "init_ldap: control/ipvirtualbasedn: %s not found\n",
+ local_ip);
+
+ constmap_free(&map_ip_dn);
+ return 0;
+ }
+}
+#endif
+
/****** LDAP OPEN, BIND & CLOSE *********************************************/
int
@@ -383,7 +528,7 @@
tv.tv_sec = ldap_timeout;
tv.tv_usec = 0;
- rc = ldap_search_st(q->ld, basedn.s, LDAP_SCOPE_SUBTREE,
+ rc = ldap_search_st(q->ld, qldap_basedn(), LDAP_SCOPE_SUBTREE,
filter, (char **)attrs, 0, &tv, &q->res);
switch (rc) {
--- qldap.h.old 2005-07-13 15:53:33.971238688 -0500
+++ qldap.h 2005-07-13 15:53:47.580169816 -0500
@@ -52,6 +52,12 @@
int qldap_need_rebind(void);
char *qldap_basedn(void);
qldap *qldap_new(void);
+#ifdef NAMED_VIRTUAL
+int virtual_login(stralloc*);
+#endif
+#ifdef IP_VIRTUAL
+int virtual_ip(const char*);
+#endif
/* possible errors:
* init: FAILED, ERRNO
--- qmail-ldap.h.old 2005-07-13 15:53:33.974238232 -0500
+++ qmail-ldap.h 2005-07-13 15:53:47.583169360 -0500
@@ -187,4 +187,13 @@
#define DO_DOT 0x02
#define DO_BOTH (DO_LDAP | DO_DOT)
+#if defined(IP_VIRTUAL) || defined (NAMED_VIRTUAL)
+#define VIRTUAL_DN
+/* Separator between username and domain part. Needed only when using
+ * username-based virtual domains.
+ * NOTE: if you change this value, you should probably check testvektor
+ * in check.c !!! */
+#define VIRTUAL_SEPARATOR '@'
+#endif
+
#endif