Alle 22:41, lunedì 3 luglio 2006, hai scritto:
> There's an argument for changing the client->authdaemon protocol to be able
> to pass arbitary environment variable settings 
this is almost what I did in my patch (limited to the LDAP_FILTER variable, 
but if it could be useful to any other person, I can extend it).

I'd like my job to be useful  to the community, so  I wanted to discuss about 
my implementation.

> (which could include 
> TCPREMOTEIP); that could be a fairly major shakeup though.
shortly:
can that protocol be changed?
if so, can that protocol be changed in the way I do?
or, which is the best way to do this?

I attach my patch to courier-authlib-0.58: it does a bit more than passing 
LDAP_FILTER between client and authdaemon, but if you ignore it the behavior 
won't change.

the game is to set LDAP_FILTER in the env of imapd thru the accesslist file 
used by couriertcpd
ex. #couriertcp -access=accessfile.dat

Thank you *very* much for your answer,
Rob.

-- 

Roberto Polli
Babel S.r.l. - http://www.babel.it
Tel. +39.06.91801075 - fax +39.06.91612446
P.zza S.Benedetto da Norcia, 33 - 00040 Pomezia (Roma)
--- original/courier-authlib-0.58-00/authdaemon.c	2005-06-30 18:16:07.000000000 +0200
+++ courier-authlib-0.58/authdaemon.c	2006-07-04 13:06:36.000000000 +0200
@@ -41,7 +41,31 @@
 {
 	char	tbuf[NUMBUFSIZE];
-	size_t	l=strlen(service)+strlen(authtype)+strlen(authdata)+2;
+	/** rpolli: getenv LDAP_FILTER if defined */
+	char *f = getenv("LDAP_FILTER");
+	size_t flen = f ? strlen(f) : 0;
+
+	if (flen > 256) { /** if LDAP_FILTER is too long, fallback to standard filter */
+			fprintf(stderr, "LDAP_FILTER too long: more than 256 chars\n");
+			flen=0;
+	}
+	
+	char *authdata1= malloc(flen+strlen(authdata)+13+2);
+	if (!authdata1)
+	{
+		perror("malloc");
+		return 1;
+	}
+			
+	if (f && flen)
+	{
+		strcat(strcat(strcpy(authdata1,"LDAP_FILTER="),getenv("LDAP_FILTER")),"\n");
+	}
+		strcat(authdata1,authdata);
+	/** */
+	
+	size_t	l=strlen(service)+strlen(authtype)+strlen(authdata1)+2;
 	char	*n=libmail_str_size_t(l, tbuf);
-	char	*buf=malloc(strlen(n)+l+20);
+ 	char	*buf=malloc(strlen(n)+l+20);
+
 	int	rc;
 
@@ -49,13 +73,17 @@
 
 	if (!buf)
+	{
+		free(authdata1);
 		return 1;
-
+	}
+	
 	strcat(strcat(strcpy(buf, "AUTH "), n), "\n");
 	strcat(strcat(buf, service), "\n");
 	strcat(strcat(buf, authtype), "\n");
-	strcat(buf, authdata);
-
+	strcat(buf, authdata1);
+	
 	rc=authdaemondo(buf, callback_func, callback_arg);
 	free(buf);
+	free (authdata1);
 
 	if (courier_authdebug_login_level)
--- original/courier-authlib-0.58-00/authdaemond.c	2005-07-07 03:30:46.000000000 +0200
+++ courier-authlib-0.58/authdaemond.c	2006-06-28 18:44:30.000000000 +0200
@@ -731,4 +731,7 @@
 	char	*pp;
 	struct authstaticinfolist *l;
+	char *ldapfilter; /** rpolli patch */
+
+// 	fprintf (stderr, "auth()\n"); fflush(stderr); 	/** rpolli debug */
 
 	service=p;
@@ -738,11 +741,21 @@
 	if ((p=strchr(p, '\n')) == 0)	return;
 	*p++=0;
-
+	/** patch rpolli */
+	if (!strncmp(p,"LDAP_FILTER=",12) )
+	{
+		p+=12;
+		ldapfilter=p;
+		if ((p=strchr(p, '\n')) == 0)	return;
+		*p++=0;
+		setenv("LDAP_FILTER",ldapfilter,1);	
+	}
+	/** fine patch */
+	
 	pp=malloc(strlen(p)+1);
 	if (!pp)
 	{
 		perror("CRIT: malloc() failed");
-		return;
-	}
+		return; 
+	} 
 
 	DPRINTF("received auth request, service=%s, authtype=%s", service, authtype);
@@ -759,4 +772,8 @@
 				      &printauth, &fd);
 
+		/** patch rpolli */
+		unsetenv("LDAP_FILTER");
+		/** fine patch */
+		
 		if (rc == 0)
 		{
@@ -768,4 +785,6 @@
 		{
 			DPRINTF("%s: TEMPFAIL - no more modules will be tried", modname);
+			if (rc==127) /** rpolli */
+				writeauth(fd, "FAIL 127\n", 9);
 			free(pp);
 			return;	/* Temporary error */
@@ -835,5 +854,5 @@
 		if (i < 0 || i >= sizeof(buf))	return;
 		for (j=0; j<i; j++)
-		{
+		{/** get the string that follows the protocol section, chars after chars, .*/
 			ch=getauthc(fd);
 			if (ch < 0)	return;
@@ -841,4 +860,5 @@
 		}
 		buf[j]=0;
+
 		auth(fd, buf);
 	}
--- original/courier-authlib-0.58-00/authdaemonlib.c	2005-10-01 17:20:52.000000000 +0200
+++ courier-authlib-0.58/authdaemonlib.c	2006-07-04 13:40:58.000000000 +0200
@@ -287,7 +287,11 @@
 			return ( (*func)(&a, arg));
 		}
-		if (strcmp(p, "FAIL") == 0)
+		if (strncmp(p, "FAIL",4) == 0)
 		{
 			errno=EPERM;
+			/** rpolli: parses the string looking for an error code \note this way supports max 3digit error codes */
+			if (strncmp(p+5,"127",3) == 0)
+				return (-127);
+			/** rpolli end */
 			return (-1);
 		}
--- original/courier-authlib-0.58-00/authdaemonrc	2006-06-26 17:10:45.000000000 +0200
+++ courier-authlib-0.58/authdaemonrc	2006-06-27 12:12:35.000000000 +0200
@@ -58,5 +58,5 @@
 # used by various configuration and build scripts, so don't touch it!
 
-authdaemonvar=/usr//var/spool/authdaemon
+authdaemonvar=/usr/var/spool/authdaemon
 
 ##NAME: DEBUG_LOGIN:0
--- original/courier-authlib-0.58-00/authldaplib.c	2005-10-01 05:33:06.000000000 +0200
+++ courier-authlib-0.58/authldaplib.c	2006-07-04 13:39:57.000000000 +0200
@@ -132,4 +132,5 @@
 	const char *mail;
         const char *filter;
+        const char *alternative_filter;
         const char *enumerate_filter;
 	const char *domain;
@@ -427,5 +428,13 @@
 		ldap->filter=p;
 	}
-
+	
+	/** patch rpolli */
+	ldap->alternative_filter=0;
+	p=0;
+	if (read_env("LDAP_ALTERNATIVE_FILTER", &p, "", 0, "") && p && strlen (p))
+	{
+		ldap->alternative_filter=p;
+	}
+	/** end patch */
 	ldap->enumerate_filter=0;
 	p=0;
@@ -1058,4 +1067,5 @@
 	LDAPMessage *entry;
 	char *filter, *dn;
+	 char *alternative_filter = NULL;
 	int i, j;
 
@@ -1073,4 +1083,28 @@
         int additionalFilter = 0;
         int hasAdditionalFilter = 0;
+		/** rpolli patch */
+		int hasAlternativeFilter = 0, alternativeFilter = 0;
+		char *hasNewFilter = getenv("LDAP_FILTER");
+		char newfilter[256];
+		char *oldfilter = NULL;
+		int lNewFilter = hasNewFilter ? strlen(hasNewFilter) : 0;
+		memset(newfilter, 0, sizeof(newfilter));
+		  
+			if (hasNewFilter && lNewFilter < 255)
+			{
+				strncpy(newfilter, hasNewFilter, lNewFilter); /* lNewFilter < 255, so it's ok */
+				DPRINTF("overriding LDAP_FILTER with [%s]", newfilter);
+				if (  (oldfilter = strdup(my_ldap.filter))  == 0 )
+				{
+					perror("strdup");
+					return 1;
+				}
+				my_ldap.filter = newfilter;
+			}
+			else
+				DPRINTF("new LDAP_FILTER undefined, using default");
+			
+		  /** */
+	/** begin prepare additionalFilter */
 
         hasAdditionalFilter = my_ldap.filter != 0;
@@ -1087,4 +1121,5 @@
         }
 
+
 	if ((filter=malloc(additionalFilter+strlen(attrname)+strlen(user)+
 			   (my_ldap.domain ? strlen(my_ldap.domain):0)+
@@ -1112,5 +1147,40 @@
         }
 
-	DPRINTF("using search filter: %s", filter);
+	DPRINTF("using search filter: %s, %s", filter, my_ldap.filter);
+	/** end prepare additionalFilter */
+	/** begin prepare alternativeFilter */
+
+	hasAlternativeFilter = my_ldap.alternative_filter != 0;
+
+	if (hasAlternativeFilter)
+	{
+            /* To add the additional filter, we need to add on the
+		* additional size for "(&)" and the other filter.  So
+		* filter+3
+				*/
+		alternativeFilter = strlen(my_ldap.alternative_filter) + 3;
+	
+		if ((alternative_filter=malloc(alternativeFilter+strlen(attrname)+strlen(user)+
+				(my_ldap.domain ? strlen(my_ldap.domain):0)+
+				sizeof ("(=@)"))) == 0)
+		{
+			perror("malloc");
+			return 1;
+		}
+		strcpy(alternative_filter, "\0");
+	
+			strcat(alternative_filter, "(&");
+			strcat(alternative_filter, my_ldap.alternative_filter);
+
+		strcat(strcat(strcat(strcat(alternative_filter, "("), attrname), "="), user);
+		if ( my_ldap.domain && my_ldap.domain[0] && strchr(user, '@') == 0 )
+			strcat(strcat(alternative_filter, "@"), my_ldap.domain);
+		strcat(alternative_filter, ")");
+			
+		strcat(alternative_filter, ")");
+		
+		DPRINTF("using alternative search filter: %s", alternative_filter ? alternative_filter : "NONE");
+	}
+	/** end prepare alternativeFilter */
 
 	timeout.tv_sec=my_ldap.timeout;
@@ -1141,4 +1211,5 @@
 	my_ldap.attrlist[j]=0;
 
+	DPRINTF("rpolli: trying first search");
 	if (ldaperror(ldap_search_st(my_ldap_fp,
 				     (char *)my_ldap.basedn,LDAP_SCOPE_SUBTREE,
@@ -1146,23 +1217,52 @@
 				     &timeout, &result))
 		      != LDAP_SUCCESS)
-	{
+	{		
 		DPRINTF("ldap_search_st() failed");
+
 		free(filter);
 
+		if (alternative_filter)
+			free(alternative_filter);
+
 		if (my_ldap_fp)	return (-1);
 		return (1);
 	}
-
+	/** rpolli patch */
+	if (oldfilter)
+		my_ldap.filter = oldfilter;
+	/** */
 	free(filter);
 
+	
 	/* If we are more than one result, reject */
-	if (ldap_count_entries(my_ldap_fp,result)!=1)
+	int count_entries = ldap_count_entries(my_ldap_fp,result);
+	if (count_entries!= 1)
 	{
 		DPRINTF("number of entries returned: %d (but we need exactly 1)",
-			ldap_count_entries(my_ldap_fp,result));
+		ldap_count_entries(my_ldap_fp,result));
+		
+		/** patch rpolli: if search with ALTERNATIVE_FILTER is ok, return -127 */
+		int retval = -1;
+		if (!count_entries && alternative_filter && (ldaperror(ldap_search_st(my_ldap_fp,
+			 (char *)my_ldap.basedn,LDAP_SCOPE_SUBTREE,
+			 alternative_filter, (char **)my_ldap.attrlist, 0,
+			 &timeout, &result))
+				  == LDAP_SUCCESS) && (ldap_count_entries(my_ldap_fp,result) == 1))
+		{
+			DPRINTF("LDAP_ALTERNATIVE_FILTER: user not allowed");
+			retval = -127;
+		}
+	
+	
+
 		ldap_msgfree(result);
-		return -1;
+		if (alternative_filter) /** rpolli */
+			free(alternative_filter);
+		return -retval;
+		/** */
 	}
-
+	if (alternative_filter)
+		free(alternative_filter);
+		
 	dn = ldap_get_dn(my_ldap_fp, result);
 
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Courier-imap mailing list
[email protected]
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-imap

Reply via email to