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

Reply via email to