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