Skip to content

Commit

Permalink
Allow ACL override by ldapcheck clauses (Piotr Wadas)
Browse files Browse the repository at this point in the history
  • Loading branch information
manu committed Jun 8, 2009
1 parent 34d97d5 commit d4af7a5
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 132 deletions.
1 change: 1 addition & 0 deletions ChangeLog
@@ -1,4 +1,5 @@
4.3.3
Allow ACL override by ldapcheck clauses (Piotr Wadas)
Header for autowhitelisted messages bug fix (Attila Bruncsak)
Fix MX sync stop on config reload (Attila Bruncsak, Hajimu UMEMOTO)
Improve Debian startup script (Adam Katz)
Expand Down
109 changes: 106 additions & 3 deletions acl.c
@@ -1,4 +1,4 @@
/* $Id: acl.c,v 1.90 2009/04/16 12:33:19 manu Exp $ */
/* $Id: acl.c,v 1.91 2009/06/08 23:40:06 manu Exp $ */

/*
* Copyright (c) 2004-2007 Emmanuel Dreyfus
Expand Down Expand Up @@ -34,7 +34,7 @@
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#ifdef __RCSID
__RCSID("$Id: acl.c,v 1.90 2009/04/16 12:33:19 manu Exp $");
__RCSID("$Id: acl.c,v 1.91 2009/06/08 23:40:06 manu Exp $");
#endif
#endif

Expand Down Expand Up @@ -2522,7 +2522,7 @@ acl_add_report(report)
}

void
acl_add_addheader(hdr)
acl_add_addheader(hdr)
char *hdr;
{
if (gacl->a_addheader) {
Expand All @@ -2542,3 +2542,106 @@ acl_add_addheader(hdr)

return;
}

int
acl_modify_by_prop(key, value, ap)
char *key;
char *value;
struct acl_param *ap;
{
if (conf.c_acldebug)
mg_log(LOG_DEBUG, "check got \"%s\" => \"%s\"",
key, value);
if (strcasecmp(key, "milterGreylistStatus") == 0) {
if ((strcasecmp(value, "Ok") == 0) ||
(strcasecmp(value, "TRUE") == 0))
goto out;
}

if (strcasecmp(key, "milterGreylistAction") == 0) {
if (strcasecmp(value, "greylist") == 0)
ap->ap_type = A_GREYLIST;
else if (strcasecmp(value, "blacklist") == 0)
ap->ap_type = A_BLACKLIST;
else if (strcasecmp(value, "whitelist") == 0)
ap->ap_type = A_WHITELIST;
else
mg_log(LOG_WARNING, "ignored greylist-type \"%s\"",
value);
goto out;
}

if (strcasecmp(key, "milterGreylistDelay") == 0) {
ap->ap_delay = humanized_atoi(value);
goto out;
}

if (strcasecmp(key, "milterGreylistAutowhite") == 0) {
ap->ap_autowhite = humanized_atoi(value);
goto out;
}

if (strcasecmp(key, "milterGreylistFlushAddr") == 0) {
ap->ap_flags |= A_FLUSHADDR;
goto out;
}

if (strcasecmp(key, "milterGreylistNoLog") == 0) {
ap->ap_flags |= A_NOLOG;
goto out;
}

if (strcasecmp(key, "milterGreylistCode") == 0) {
if ((ap->ap_code = strdup(value)) == NULL) {
mg_log(LOG_ERR, "strdup(\"%s\") failed: %s",
key, strerror(errno));
exit(EX_OSERR);
}
ap->ap_flags |= A_FREE_CODE;
goto out;
}

if (strcasecmp(key, "milterGreylistEcode") == 0) {
if ((ap->ap_ecode = strdup(value)) == NULL) {
mg_log(LOG_ERR, "strdup(\"%s\") failed: %s",
key, strerror(errno));
exit(EX_OSERR);
}
ap->ap_flags |= A_FREE_ECODE;
goto out;
}

if (strcasecmp(key, "milterGreylistMsg") == 0) {
if ((ap->ap_msg = strdup(value)) == NULL) {
mg_log(LOG_ERR, "strdup(\"%s\") failed: %s",
key, strerror(errno));
exit(EX_OSERR);
}
ap->ap_flags |= A_FREE_MSG;
goto out;
}

if (strcasecmp(key, "milterGreylistReport") == 0) {
if ((ap->ap_report = strdup(value)) == NULL) {
mg_log(LOG_ERR, "strdup(\"%s\") failed: %s",
key, strerror(errno));
exit(EX_OSERR);
}
ap->ap_flags |= A_FREE_REPORT;
goto out;
}

if (strcasecmp(key, "milterGreylistIgnore") == 0)
goto out;
if (conf.c_acldebug)
mg_log(LOG_DEBUG, "acl_modify inexpected property "
"\"%s\"=\"%s\"", key, value);

return -1;
out:
if (conf.c_acldebug)
mg_log(LOG_DEBUG, "modified acl property "
"\"%s\"=\"%s\"", key, value);

return 0;
}
4 changes: 2 additions & 2 deletions acl.h
@@ -1,4 +1,4 @@
/* $Id: acl.h,v 1.39 2008/11/26 05:20:13 manu Exp $ */
/* $Id: acl.h,v 1.40 2009/06/08 23:40:06 manu Exp $ */

/*
* Copyright (c) 2004-2007 Emmanuel Dreyfus
Expand Down Expand Up @@ -316,7 +316,7 @@ int acl_msgsize_cmp(acl_data_t *, acl_stage_t,
int acl_opnum_cmp(int, enum operator, int);
int myregexec(struct mlfi_priv *, acl_data_t *,
struct acl_param *, const char *);

int acl_modify_by_prop(char *, char *, struct acl_param *);
/* acl_filter() return codes */
#define EXF_UNSET 0
#define EXF_GREYLIST (1 << 0)
Expand Down
6 changes: 5 additions & 1 deletion conf_lex.l
Expand Up @@ -61,6 +61,8 @@ delay -?[0-9]+[smhdw]?
qstring "\""([^"\n]|\\\")+"\""
regex "/"([^/\n]|\\"/")+"/"
dumpfreq [Dd][Uu][Mm][Pp][Ff][Rr][Ee][Qq]:?
binddn [Bb][Ii][Nn][Dd][Dd][Nn]
bindpw [Bb][Ii][Nn][Dd][Pp][Ww]
timeout [Tt][Ii][Mm][Ee][Oo][Uu][Tt]:?
time [Tt][Ii][Mm][Ee]
domain [Dd][Oo][Mm][Aa][Ii][Nn]:?
Expand Down Expand Up @@ -161,7 +163,7 @@ domainexact [Dd][Oo][Mm][Aa][Ii][Nn][Ee][Xx][Aa][Cc][Tt]
#ifndef HAVE_BROKEN_RCSID
#include <sys/cdefs.h>
#ifdef __RCSID
__RCSID("$Id: conf_lex.l,v 1.89 2009/01/17 04:32:55 manu Exp $");
__RCSID("$Id: conf_lex.l,v 1.90 2009/06/08 23:40:06 manu Exp $");
#endif
#endif
#endif
Expand Down Expand Up @@ -308,6 +310,8 @@ domainexact [Dd][Oo][Mm][Aa][Ii][Nn][Ee][Xx][Aa][Cc][Tt]
{all} { return ALL; }
{dumpfreq} { return GLDUMPFREQ; }
{timeout} { return GLTIMEOUT; }
{binddn} { return LDAPBINDDN; }
{bindpw} { return LDAPBINDPW; }
{time} { BEGIN(S_CLOCKSPEC1); return TIME; }
{domain} { BEGIN(S_REGEX); return DOMAIN; }
{syncaddr} { return SYNCADDR; }
Expand Down
29 changes: 24 additions & 5 deletions conf_yacc.y
Expand Up @@ -14,15 +14,16 @@
%token LOGFAC_NEWS LOGFAC_UUCP LOGFAC_CRON LOGFAC_AUTHPRIV LOGFAC_FTP
%token LOGFAC_LOCAL0 LOGFAC_LOCAL1 LOGFAC_LOCAL2 LOGFAC_LOCAL3 LOGFAC_LOCAL4
%token LOGFAC_LOCAL5 LOGFAC_LOCAL6 LOGFAC_LOCAL7 P0F P0FSOCK DKIMCHECK
%token SPAMDSOCK SPAMDSOCKT SPAMD DOMAINEXACT ADDHEADER NOLOG
%token SPAMDSOCK SPAMDSOCKT SPAMD DOMAINEXACT ADDHEADER NOLOG LDAPBINDDN
%token LDAPBINDPW

%{
#include "config.h"

#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#ifdef __RCSID
__RCSID("$Id: conf_yacc.y,v 1.101 2009/04/09 03:36:30 manu Exp $");
__RCSID("$Id: conf_yacc.y,v 1.102 2009/06/08 23:40:06 manu Exp $");
#endif
#endif

Expand Down Expand Up @@ -1386,17 +1387,35 @@ urlcheckdef_fork: FORK {
}
;

ldapconfdef: LDAPCONF QSTRING ldaptimeout {
ldapconfdef: LDAPCONF QSTRING ldaptimeout
LDAPBINDDN QSTRING LDAPBINDPW QSTRING {
#ifdef USE_LDAP
char uris[QSTRLEN + 1];

ldapcheck_conf_add(quotepath(uris, $2, QSTRLEN));
char bdn[QSTRLEN +1 ];
char bpw[QSTRLEN + 1 ];
ldapcheck_conf_add(
quotepath(uris, $2, QSTRLEN),
quotepath(bdn, $5, QSTRLEN),
quotepath(bpw, $7, QSTRLEN));
#else
mg_log(LOG_INFO,
"LDAP support not compiled in, ignore line %d",
conf_line);
#endif
}
| LDAPCONF QSTRING ldaptimeout { /* 4.2.1 backward compatiblity */
#ifdef USE_LDAP
char uris[QSTRLEN + 1];
char *bdn = NULL;
char *bpw = NULL;
ldapcheck_conf_add(
quotepath(uris, $2, QSTRLEN), bdn, bpw);
#else
mg_log(LOG_INFO,
"LDAP support not compiled in, ignore line %d",
conf_line);
#endif
}
;
ldaptimeout: GLTIMEOUT TDELAY {
#ifdef USE_LDAP
Expand Down
61 changes: 44 additions & 17 deletions ldapcheck.c
@@ -1,4 +1,4 @@
/* $Id: ldapcheck.c,v 1.7 2009/04/09 03:27:20 manu Exp $ */
/* $Id: ldapcheck.c,v 1.8 2009/06/08 23:40:06 manu Exp $ */

/*
* Copyright (c) 2008 Emmanuel Dreyfus
Expand Down Expand Up @@ -36,7 +36,7 @@
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#ifdef __RCSID
__RCSID("$Id: ldapcheck.c,v 1.7 2009/04/09 03:27:20 manu Exp $");
__RCSID("$Id: ldapcheck.c,v 1.8 2009/06/08 23:40:06 manu Exp $");
#endif
#endif
#include <ctype.h>
Expand Down Expand Up @@ -71,7 +71,7 @@ struct ldapconf_entry {
SIMPLEQ_HEAD(ldapconf_list, ldapconf_entry);
LIST_HEAD(ldapcheck_list, ldapcheck_entry);

static void ldapcheck_conf_addone(char *);
static void ldapcheck_conf_addone(char *, char *, char *);
static int ldapcheck_connect(struct ldapconf_entry *);
static int ldapcheck_disconnect(struct ldapconf_entry *);
static char *url_encode_percent(char *);
Expand All @@ -81,6 +81,8 @@ static inline void ldapcheck_unlock(struct ldapconf_entry *);
static struct ldapcheck_list ldapcheck_list;
static struct ldapconf_list ldapconf_list;
static struct timeval ldap_timeout;
static char *ldap_binddn;
static char *ldap_bindpw;

int ldapcheck_gflags = 0;

Expand All @@ -96,8 +98,10 @@ ldapcheck_init(void) {
}

static void
ldapcheck_conf_addone(url)
ldapcheck_conf_addone(url, binddn, bindpw)
char *url;
char *binddn;
char *bindpw;
{
struct ldapconf_entry *lc;

Expand All @@ -113,6 +117,16 @@ ldapcheck_conf_addone(url)

lc->lc_dn = NULL;
lc->lc_pwd = NULL;
if ((binddn != NULL) && (lc->lc_dn = strdup(binddn)) == NULL) {
mg_log(LOG_ERR, "strdup failed: %s", strerror(errno));
exit(EX_OSERR);
}

if ((bindpw != NULL) && (lc->lc_pwd = strdup(bindpw)) == NULL) {
mg_log(LOG_ERR, "strdup failed: %s", strerror(errno));
exit(EX_OSERR);
}

lc->lc_ld = NULL;
lc->lc_refcount = 0;
if (pthread_mutex_init(&lc->lc_lock, NULL) != 0) {
Expand All @@ -127,19 +141,24 @@ ldapcheck_conf_addone(url)
}

void
ldapcheck_conf_add(urls)
ldapcheck_conf_add(urls, binddn, bindpw)
char *urls;
char *binddn;
char *bindpw;
{
char *lasts = NULL;
char *p;
char *sep = "\t ";

if (conf.c_debug || conf.c_acldebug) {
mg_log(LOG_DEBUG, "bind options dn =\"%s\", pwd = \"%s\"\n",
binddn, bindpw);
}
if ((p = strtok_r(urls, sep, &lasts)) != NULL) {
ldapcheck_conf_addone(p);
ldapcheck_conf_addone(p, binddn, bindpw);

while (p)
if ((p = strtok_r(NULL, sep, &lasts)) != NULL)
ldapcheck_conf_addone(p);
ldapcheck_conf_addone(p, binddn, bindpw);
}

return;
Expand Down Expand Up @@ -264,10 +283,10 @@ ldapcheck_connect(lc)
}

error = ldap_simple_bind_s(lc->lc_ld, lc->lc_dn, lc->lc_pwd);
if (error != 0) {
if (error != LDAP_SUCCESS) {
mg_log(LOG_WARNING,
"ldap_simple_bind_s failed for LDAP URL \"%s\": %s",
lc->lc_url, ldap_err2string(error));
"ldap_simple_bind_s (%s/%s) failed for LDAP URL \"%s\": %s",
lc->lc_dn, lc->lc_pwd, lc->lc_url, ldap_err2string(error));
goto bad;
}

Expand Down Expand Up @@ -338,7 +357,7 @@ ldapcheck_validate(ad, stage, ap, priv)
struct timeval tv1, tv2, tv3;
LDAPMessage *res0 = NULL;
LDAPMessage *res = NULL;
int error;
int error,pushed = 0 ;
int retval = -1;
int clearprop;

Expand Down Expand Up @@ -430,13 +449,21 @@ ldapcheck_validate(ad, stage, ap, priv)

vals = ldap_get_values(lc->lc_ld, res, attr);
if (vals == NULL) {
mg_log(LOG_ERR, "ldap_get_values for URL \"%s\""
"returns vals = NULL", url);
goto bad;
mg_log(LOG_ERR, "ldap_get_values for URL \"%s\" attr %s "
"returns vals = NULL", attr, url);
ldap_value_free(vals);
ldap_memfree(attr);
continue;
}

for (val = vals; *val; val++)
for (val = vals; *val; val++)
{
acl_modify_by_prop(attr, *val, ap);
prop_push(attr, *val, clearprop, priv);
pushed++;
if (conf.c_acldebug) mg_log(LOG_DEBUG,
"acl debug: pushed prop %s: %s", attr,*val);
}

ldap_value_free(vals);
ldap_memfree(attr);
Expand All @@ -446,7 +473,7 @@ ldapcheck_validate(ad, stage, ap, priv)
ber_free(ber, 0);
}

retval = 0;
retval = pushed ? 1 : 0 ;
bad:
if (res0)
ldap_msgfree(res0);
Expand Down

0 comments on commit d4af7a5

Please sign in to comment.